FIX: Make sure we add a TTL when we enable readonly mode.

This commit is contained in:
Guo Xiang Tan 2016-06-29 13:55:17 +08:00
parent 83b08b87d5
commit 7619c2fa2f
No known key found for this signature in database
GPG Key ID: 19C321C8952B0F72
2 changed files with 56 additions and 35 deletions

View File

@ -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

View File

@ -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