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:
parent
9518e47204
commit
2df0eca39a
|
@ -594,6 +594,8 @@ module Discourse
|
||||||
alias_method :base_url_no_path, :base_url_no_prefix
|
alias_method :base_url_no_path, :base_url_no_prefix
|
||||||
end
|
end
|
||||||
|
|
||||||
|
LAST_POSTGRES_READONLY_KEY = "postgres:last_readonly"
|
||||||
|
|
||||||
READONLY_MODE_KEY_TTL ||= 60
|
READONLY_MODE_KEY_TTL ||= 60
|
||||||
READONLY_MODE_KEY ||= "readonly_mode"
|
READONLY_MODE_KEY ||= "readonly_mode"
|
||||||
PG_READONLY_MODE_KEY ||= "readonly_mode:postgres"
|
PG_READONLY_MODE_KEY ||= "readonly_mode:postgres"
|
||||||
|
@ -704,7 +706,7 @@ module Discourse
|
||||||
|
|
||||||
# Shared between processes
|
# Shared between processes
|
||||||
def self.postgres_last_read_only
|
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
|
end
|
||||||
|
|
||||||
# Per-process
|
# Per-process
|
||||||
|
@ -712,20 +714,33 @@ module Discourse
|
||||||
@redis_last_read_only ||= {}
|
@redis_last_read_only ||= {}
|
||||||
end
|
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?
|
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 = redis_last_read_only[Discourse.redis.namespace]
|
||||||
|
|
||||||
(redis_read_only.present? && redis_read_only > 15.seconds.ago) ||
|
(redis_read_only.present? && redis_read_only > 15.seconds.ago) || postgres_recently_readonly?
|
||||||
(postgres_read_only.present? && postgres_read_only > 15.seconds.ago)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.received_postgres_readonly!
|
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
|
end
|
||||||
|
|
||||||
def self.clear_postgres_readonly!
|
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
|
end
|
||||||
|
|
||||||
def self.received_redis_readonly!
|
def self.received_redis_readonly!
|
||||||
|
|
|
@ -311,7 +311,7 @@ RSpec.describe Discourse do
|
||||||
describe ".received_postgres_readonly!" do
|
describe ".received_postgres_readonly!" do
|
||||||
it "sets the right time" do
|
it "sets the right time" do
|
||||||
time = Discourse.received_postgres_readonly!
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ RSpec.describe Discourse do
|
||||||
messages = []
|
messages = []
|
||||||
|
|
||||||
expect do messages = MessageBus.track_publish { Discourse.clear_readonly! } end.to change {
|
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)
|
}.to(nil)
|
||||||
|
|
||||||
expect(messages.any? { |m| m.channel == Site::SITE_JSON_CHANNEL }).to eq(true)
|
expect(messages.any? { |m| m.channel == Site::SITE_JSON_CHANNEL }).to eq(true)
|
||||||
|
|
Loading…
Reference in New Issue