From 7619c2fa2f445f0c2725f2921377e89e6ef0a580 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Wed, 29 Jun 2016 13:55:17 +0800 Subject: [PATCH] FIX: Make sure we add a TTL when we enable readonly mode. --- lib/discourse.rb | 6 ++- spec/components/discourse_spec.rb | 85 +++++++++++++++++++------------ 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/lib/discourse.rb b/lib/discourse.rb index 762c1c0eaa5..fe0684a4b4e 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -215,8 +215,10 @@ module Discourse base_url_no_prefix + base_uri end + READONLY_MODE_KEY_TTL ||= 60 + def self.enable_readonly_mode - $redis.set(readonly_mode_key, 1) + $redis.setex(readonly_mode_key, READONLY_MODE_KEY_TTL, 1) MessageBus.publish(readonly_channel, true) keep_readonly_mode true @@ -226,7 +228,7 @@ module Discourse # extend the expiry by 1 minute every 30 seconds Thread.new do while readonly_mode? - $redis.expire(readonly_mode_key, 1.minute) + $redis.expire(readonly_mode_key, READONLY_MODE_KEY_TTL) sleep 30.seconds end end diff --git a/spec/components/discourse_spec.rb b/spec/components/discourse_spec.rb index b8b108519e0..49948f6c513 100644 --- a/spec/components/discourse_spec.rb +++ b/spec/components/discourse_spec.rb @@ -85,50 +85,69 @@ describe Discourse do end - context "#enable_readonly_mode" do + context 'readonly mode' do + let(:readonly_channel) { Discourse.readonly_channel } + let(:readonly_key) { Discourse.readonly_mode_key } + let(:readonly_mode_ttl) { Discourse::READONLY_MODE_KEY_TTL } - it "adds a key in redis and publish a message through the message bus" do - $redis.expects(:set).with(Discourse.readonly_mode_key, 1) - MessageBus.expects(:publish).with(Discourse.readonly_channel, true) - Discourse.enable_readonly_mode + after do + $redis.del(readonly_key) end - end - - context "#disable_readonly_mode" do - - it "removes a key from redis and publish a message through the message bus" do - $redis.expects(:del).with(Discourse.readonly_mode_key) - MessageBus.expects(:publish).with(Discourse.readonly_channel, false) - Discourse.disable_readonly_mode + def assert_readonly_mode(message, channel, key, ttl) + expect(message.channel).to eq(channel) + expect(message.data).to eq(true) + expect($redis.get(key)).to eq("1") + expect($redis.ttl(key)).to eq(ttl) end - end - - context "#readonly_mode?" do - it "is false by default" do - expect(Discourse.readonly_mode?).to eq(false) + def assert_readonly_mode_disabled(message, channel, key) + expect(message.channel).to eq(channel) + expect(message.data).to eq(false) + expect($redis.get(key)).to eq(nil) end - it "returns true when the key is present in redis" do - begin - $redis.set(Discourse.readonly_mode_key, 1) - expect(Discourse.readonly_mode?).to eq(true) - ensure - $redis.del(Discourse.readonly_mode_key) + context ".enable_readonly_mode" do + it "adds a key in redis and publish a message through the message bus" do + expect($redis.get(readonly_key)).to eq(nil) + message = MessageBus.track_publish { Discourse.enable_readonly_mode }.first + assert_readonly_mode(message, readonly_channel, readonly_key, readonly_mode_ttl) end end - it "returns true when Discourse is recently read only" do - Discourse.received_readonly! - expect(Discourse.readonly_mode?).to eq(true) - end - end + context ".disable_readonly_mode" do + it "removes a key from redis and publish a message through the message bus" do + Discourse.enable_readonly_mode - context ".received_readonly!" do - it "sets the right time" do - time = Discourse.received_readonly! - expect(Discourse.last_read_only['default']).to eq(time) + message = MessageBus.track_publish do + Discourse.disable_readonly_mode + end.first + + assert_readonly_mode_disabled(message, readonly_channel, readonly_key) + end + end + + context ".readonly_mode?" do + it "is false by default" do + expect(Discourse.readonly_mode?).to eq(false) + end + + it "returns true when the key is present in redis" do + $redis.set(readonly_key, 1) + expect(Discourse.readonly_mode?).to eq(true) + end + + it "returns true when Discourse is recently read only" do + Discourse.received_readonly! + expect(Discourse.readonly_mode?).to eq(true) + end + end + + context ".received_readonly!" do + it "sets the right time" do + time = Discourse.received_readonly! + expect(Discourse.last_read_only['default']).to eq(time) + end end end