mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 23:58:31 -05:00
FIX: Set a not expiring key for user enabled readonly mode.
This commit is contained in:
parent
7619c2fa2f
commit
64858c10fe
3 changed files with 48 additions and 27 deletions
|
@ -95,7 +95,7 @@ class Admin::BackupsController < Admin::AdminController
|
||||||
|
|
||||||
def readonly
|
def readonly
|
||||||
enable = params.fetch(:enable).to_s == "true"
|
enable = params.fetch(:enable).to_s == "true"
|
||||||
enable ? Discourse.enable_readonly_mode : Discourse.disable_readonly_mode
|
enable ? Discourse.enable_readonly_mode(user_enabled: true) : Discourse.disable_readonly_mode(user_enabled: true)
|
||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -216,11 +216,18 @@ module Discourse
|
||||||
end
|
end
|
||||||
|
|
||||||
READONLY_MODE_KEY_TTL ||= 60
|
READONLY_MODE_KEY_TTL ||= 60
|
||||||
|
READONLY_MODE_KEY ||= 'readonly_mode'.freeze
|
||||||
|
USER_READONLY_MODE_KEY ||= 'readonly_mode:user'.freeze
|
||||||
|
|
||||||
def self.enable_readonly_mode
|
def self.enable_readonly_mode(user_enabled: false)
|
||||||
$redis.setex(readonly_mode_key, READONLY_MODE_KEY_TTL, 1)
|
if user_enabled
|
||||||
MessageBus.publish(readonly_channel, true)
|
$redis.set(USER_READONLY_MODE_KEY, 1)
|
||||||
|
else
|
||||||
|
$redis.setex(READONLY_MODE_KEY, READONLY_MODE_KEY_TTL, 1)
|
||||||
keep_readonly_mode
|
keep_readonly_mode
|
||||||
|
end
|
||||||
|
|
||||||
|
MessageBus.publish(readonly_channel, true)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -228,20 +235,21 @@ module Discourse
|
||||||
# extend the expiry by 1 minute every 30 seconds
|
# extend the expiry by 1 minute every 30 seconds
|
||||||
Thread.new do
|
Thread.new do
|
||||||
while readonly_mode?
|
while readonly_mode?
|
||||||
$redis.expire(readonly_mode_key, READONLY_MODE_KEY_TTL)
|
$redis.expire(READONLY_MODE_KEY, READONLY_MODE_KEY_TTL)
|
||||||
sleep 30.seconds
|
sleep 30.seconds
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.disable_readonly_mode
|
def self.disable_readonly_mode(user_enabled: false)
|
||||||
$redis.del(readonly_mode_key)
|
key = user_enabled ? USER_READONLY_MODE_KEY : READONLY_MODE_KEY
|
||||||
|
$redis.del(key)
|
||||||
MessageBus.publish(readonly_channel, false)
|
MessageBus.publish(readonly_channel, false)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.readonly_mode?
|
def self.readonly_mode?
|
||||||
recently_readonly? || !!$redis.get(readonly_mode_key)
|
recently_readonly? || !!$redis.get(READONLY_MODE_KEY)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.request_refresh!
|
def self.request_refresh!
|
||||||
|
@ -310,10 +318,6 @@ module Discourse
|
||||||
Rails.configuration.action_controller.asset_host
|
Rails.configuration.action_controller.asset_host
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.readonly_mode_key
|
|
||||||
"readonly_mode"
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.readonly_channel
|
def self.readonly_channel
|
||||||
"/site/read-only"
|
"/site/read-only"
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,36 +86,45 @@ describe Discourse do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'readonly mode' do
|
context 'readonly mode' do
|
||||||
let(:readonly_channel) { Discourse.readonly_channel }
|
let(:readonly_mode_key) { Discourse::READONLY_MODE_KEY }
|
||||||
let(:readonly_key) { Discourse.readonly_mode_key }
|
|
||||||
let(:readonly_mode_ttl) { Discourse::READONLY_MODE_KEY_TTL }
|
let(:readonly_mode_ttl) { Discourse::READONLY_MODE_KEY_TTL }
|
||||||
|
let(:user_readonly_mode_key) { Discourse::USER_READONLY_MODE_KEY }
|
||||||
|
|
||||||
after do
|
after do
|
||||||
$redis.del(readonly_key)
|
$redis.del(readonly_mode_key)
|
||||||
|
$redis.del(user_readonly_mode_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_readonly_mode(message, channel, key, ttl)
|
def assert_readonly_mode(message, key, ttl = -1)
|
||||||
expect(message.channel).to eq(channel)
|
expect(message.channel).to eq(Discourse.readonly_channel)
|
||||||
expect(message.data).to eq(true)
|
expect(message.data).to eq(true)
|
||||||
expect($redis.get(key)).to eq("1")
|
expect($redis.get(key)).to eq("1")
|
||||||
expect($redis.ttl(key)).to eq(ttl)
|
expect($redis.ttl(key)).to eq(ttl)
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_readonly_mode_disabled(message, channel, key)
|
def assert_readonly_mode_disabled(message, key)
|
||||||
expect(message.channel).to eq(channel)
|
expect(message.channel).to eq(Discourse.readonly_channel)
|
||||||
expect(message.data).to eq(false)
|
expect(message.data).to eq(false)
|
||||||
expect($redis.get(key)).to eq(nil)
|
expect($redis.get(key)).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
context ".enable_readonly_mode" do
|
describe ".enable_readonly_mode" do
|
||||||
it "adds a key in redis and publish a message through the message bus" do
|
it "adds a key in redis and publish a message through the message bus" do
|
||||||
expect($redis.get(readonly_key)).to eq(nil)
|
expect($redis.get(readonly_mode_key)).to eq(nil)
|
||||||
message = MessageBus.track_publish { Discourse.enable_readonly_mode }.first
|
message = MessageBus.track_publish { Discourse.enable_readonly_mode }.first
|
||||||
assert_readonly_mode(message, readonly_channel, readonly_key, readonly_mode_ttl)
|
assert_readonly_mode(message, readonly_mode_key, readonly_mode_ttl)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'user enabled readonly mode' do
|
||||||
|
it "adds a key in redis and publish a message through the message bus" do
|
||||||
|
expect($redis.get(user_readonly_mode_key)).to eq(nil)
|
||||||
|
message = MessageBus.track_publish { Discourse.enable_readonly_mode(user_enabled: true) }.first
|
||||||
|
assert_readonly_mode(message, user_readonly_mode_key)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context ".disable_readonly_mode" do
|
describe ".disable_readonly_mode" do
|
||||||
it "removes a key from redis and publish a message through the message bus" do
|
it "removes a key from redis and publish a message through the message bus" do
|
||||||
Discourse.enable_readonly_mode
|
Discourse.enable_readonly_mode
|
||||||
|
|
||||||
|
@ -123,17 +132,25 @@ describe Discourse do
|
||||||
Discourse.disable_readonly_mode
|
Discourse.disable_readonly_mode
|
||||||
end.first
|
end.first
|
||||||
|
|
||||||
assert_readonly_mode_disabled(message, readonly_channel, readonly_key)
|
assert_readonly_mode_disabled(message, readonly_mode_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'user disabled readonly mode' do
|
||||||
|
it "removes readonly key in redis and publish a message through the message bus" do
|
||||||
|
Discourse.enable_readonly_mode(user_enabled: true)
|
||||||
|
message = MessageBus.track_publish { Discourse.disable_readonly_mode(user_enabled: true) }.first
|
||||||
|
assert_readonly_mode_disabled(message, user_readonly_mode_key)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context ".readonly_mode?" do
|
describe ".readonly_mode?" do
|
||||||
it "is false by default" do
|
it "is false by default" do
|
||||||
expect(Discourse.readonly_mode?).to eq(false)
|
expect(Discourse.readonly_mode?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns true when the key is present in redis" do
|
it "returns true when the key is present in redis" do
|
||||||
$redis.set(readonly_key, 1)
|
$redis.set(readonly_mode_key, 1)
|
||||||
expect(Discourse.readonly_mode?).to eq(true)
|
expect(Discourse.readonly_mode?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -143,7 +160,7 @@ describe Discourse do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context ".received_readonly!" do
|
describe ".received_readonly!" do
|
||||||
it "sets the right time" do
|
it "sets the right time" do
|
||||||
time = Discourse.received_readonly!
|
time = Discourse.received_readonly!
|
||||||
expect(Discourse.last_read_only['default']).to eq(time)
|
expect(Discourse.last_read_only['default']).to eq(time)
|
||||||
|
|
Loading…
Reference in a new issue