DEV: Make postgres_readonly cache work like other caches (#20879)

We didn't have an authoritative source for this data previously, so now
it's stored in redis.
This commit is contained in:
Daniel Waterworth 2023-03-30 09:14:59 -05:00 committed by GitHub
parent 9518e47204
commit 2df0eca39a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 8 deletions

View File

@ -594,6 +594,8 @@ module Discourse
alias_method :base_url_no_path, :base_url_no_prefix
end
LAST_POSTGRES_READONLY_KEY = "postgres:last_readonly"
READONLY_MODE_KEY_TTL ||= 60
READONLY_MODE_KEY ||= "readonly_mode"
PG_READONLY_MODE_KEY ||= "readonly_mode:postgres"
@ -704,7 +706,7 @@ module Discourse
# Shared between processes
def self.postgres_last_read_only
@postgres_last_read_only ||= DistributedCache.new("postgres_last_read_only", namespace: false)
@postgres_last_read_only ||= DistributedCache.new("postgres_last_read_only")
end
# Per-process
@ -712,20 +714,33 @@ module Discourse
@redis_last_read_only ||= {}
end
def self.postgres_recently_readonly?
timestamp =
postgres_last_read_only.defer_get_set("timestamp") do
seconds = redis.get(LAST_POSTGRES_READONLY_KEY)
Time.zone.at(seconds.to_i) if seconds
end
timestamp.present? && timestamp > 15.seconds.ago
end
def self.recently_readonly?
postgres_read_only = postgres_last_read_only[Discourse.redis.namespace]
redis_read_only = redis_last_read_only[Discourse.redis.namespace]
(redis_read_only.present? && redis_read_only > 15.seconds.ago) ||
(postgres_read_only.present? && postgres_read_only > 15.seconds.ago)
(redis_read_only.present? && redis_read_only > 15.seconds.ago) || postgres_recently_readonly?
end
def self.received_postgres_readonly!
postgres_last_read_only[Discourse.redis.namespace] = Time.zone.now
time = Time.zone.now
redis.set(LAST_POSTGRES_READONLY_KEY, time.to_i.to_s)
postgres_last_read_only.clear
time
end
def self.clear_postgres_readonly!
postgres_last_read_only[Discourse.redis.namespace] = nil
redis.del(LAST_POSTGRES_READONLY_KEY)
postgres_last_read_only.clear
end
def self.received_redis_readonly!

View File

@ -311,7 +311,7 @@ RSpec.describe Discourse do
describe ".received_postgres_readonly!" do
it "sets the right time" do
time = Discourse.received_postgres_readonly!
expect(Discourse.postgres_last_read_only["default"]).to eq(time)
expect(Discourse.redis.get(Discourse::LAST_POSTGRES_READONLY_KEY).to_i).to eq(time.to_i)
end
end
@ -328,7 +328,7 @@ RSpec.describe Discourse do
messages = []
expect do messages = MessageBus.track_publish { Discourse.clear_readonly! } end.to change {
Discourse.postgres_last_read_only["default"]
Discourse.redis.get(Discourse::LAST_POSTGRES_READONLY_KEY)
}.to(nil)
expect(messages.any? { |m| m.channel == Site::SITE_JSON_CHANNEL }).to eq(true)