From 5406e24acb604f96ed40ed4b74f29652983c2409 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Thu, 19 Jan 2023 13:59:11 +0000 Subject: [PATCH] FEATURE: Introduce pg_force_readonly_mode GlobalSetting (#19612) This allows the entire cluster to be forced into pg readonly mode. Equivalent to running `Discourse.enable_pg_force_readonly_mode` on the console. --- config/discourse_defaults.conf | 3 +++ config/initializers/002-rails_failover.rb | 6 +++++- lib/discourse.rb | 2 +- spec/lib/discourse_spec.rb | 6 ++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/config/discourse_defaults.conf b/config/discourse_defaults.conf index 74b202d0645..b5cc812af97 100644 --- a/config/discourse_defaults.conf +++ b/config/discourse_defaults.conf @@ -365,3 +365,6 @@ preload_link_header = false # When using an external upload store, redirect `user_avatar` requests instead of proxying redirect_avatar_requests = false + +# Force the entire cluster into postgres readonly mode. Equivalent to running `Discourse.enable_pg_force_readonly_mode` +pg_force_readonly_mode = false diff --git a/config/initializers/002-rails_failover.rb b/config/initializers/002-rails_failover.rb index 276e6d951bb..d5ee5c2da24 100644 --- a/config/initializers/002-rails_failover.rb +++ b/config/initializers/002-rails_failover.rb @@ -69,7 +69,11 @@ if defined?(RailsFailover::ActiveRecord) end RailsFailover::ActiveRecord.register_force_reading_role_callback do - Discourse.redis.exists?(Discourse::PG_READONLY_MODE_KEY, Discourse::PG_FORCE_READONLY_MODE_KEY) + GlobalSetting.pg_force_readonly_mode || + Discourse.redis.exists?( + Discourse::PG_READONLY_MODE_KEY, + Discourse::PG_FORCE_READONLY_MODE_KEY, + ) rescue => e if !e.is_a?(Redis::CannotConnectError) Rails.logger.warn "#{e.class} #{e.message}: #{e.backtrace.join("\n")}" diff --git a/lib/discourse.rb b/lib/discourse.rb index 0fa1598d3cc..dfb3a0cc06d 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -691,7 +691,7 @@ module Discourse end def self.readonly_mode?(keys = READONLY_KEYS) - recently_readonly? || Discourse.redis.exists?(*keys) + recently_readonly? || GlobalSetting.pg_force_readonly_mode || Discourse.redis.exists?(*keys) end def self.staff_writes_only_mode? diff --git a/spec/lib/discourse_spec.rb b/spec/lib/discourse_spec.rb index 1a4227fe118..c0321ec6d7a 100644 --- a/spec/lib/discourse_spec.rb +++ b/spec/lib/discourse_spec.rb @@ -300,6 +300,12 @@ RSpec.describe Discourse do Discourse.disable_readonly_mode(user_readonly_mode_key) expect(Discourse.readonly_mode?).to eq(false) end + + it "returns true when forced via global setting" do + expect(Discourse.readonly_mode?).to eq(false) + global_setting :pg_force_readonly_mode, true + expect(Discourse.readonly_mode?).to eq(true) + end end describe ".received_postgres_readonly!" do