Make PostgreSQL failover work with distributed cache.
This commit is contained in:
parent
989280a222
commit
fe1e78ddf4
|
@ -7,10 +7,12 @@ class PostgreSQLFallbackHandler
|
|||
include Singleton
|
||||
|
||||
attr_reader :masters_down
|
||||
attr_accessor :initialized
|
||||
|
||||
def initialize
|
||||
@masters_down = DistributedCache.new('masters_down')
|
||||
@masters_down = DistributedCache.new('masters_down', namespace: false)
|
||||
@mutex = Mutex.new
|
||||
@initialized = false
|
||||
end
|
||||
|
||||
def verify_master
|
||||
|
@ -126,13 +128,12 @@ module ActiveRecord
|
|||
else
|
||||
begin
|
||||
connection = postgresql_connection(config)
|
||||
fallback_handler.master_down = false
|
||||
fallback_handler.initialized ||= true
|
||||
rescue PG::ConnectionBad => e
|
||||
on_boot = fallback_handler.master_down?.nil?
|
||||
fallback_handler.master_down = true
|
||||
fallback_handler.verify_master
|
||||
|
||||
if on_boot
|
||||
if !fallback_handler.initialized
|
||||
return postgresql_fallback_connection(config)
|
||||
else
|
||||
raise e
|
||||
|
|
|
@ -105,10 +105,11 @@ class DistributedCache
|
|||
|
||||
attr_reader :key
|
||||
|
||||
def initialize(key, manager = nil)
|
||||
def initialize(key, manager: nil, namespace: true)
|
||||
@key = key
|
||||
@data = {}
|
||||
@manager = manager || DistributedCache.default_manager
|
||||
@namespace = namespace
|
||||
|
||||
@manager.ensure_subscribe!
|
||||
@manager.register(self)
|
||||
|
@ -142,7 +143,14 @@ class DistributedCache
|
|||
end
|
||||
|
||||
def hash(db = nil)
|
||||
db ||= RailsMultisite::ConnectionManagement.current_db
|
||||
db ||= begin
|
||||
if @namespace
|
||||
RailsMultisite::ConnectionManagement.current_db
|
||||
else
|
||||
RailsMultisite::ConnectionManagement::DEFAULT
|
||||
end
|
||||
end
|
||||
|
||||
@data[db] ||= ThreadSafe::Hash.new
|
||||
end
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ describe ActiveRecord::ConnectionHandling do
|
|||
|
||||
it 'should failover to a replica server' do
|
||||
RailsMultisite::ConnectionManagement.stubs(:all_dbs).returns(['default', multisite_db])
|
||||
postgresql_fallback_handler.expects(:verify_master).at_least(3)
|
||||
|
||||
[config, multisite_config].each do |configuration|
|
||||
ActiveRecord::Base.expects(:postgresql_connection).with(configuration).raises(PG::ConnectionBad)
|
||||
|
@ -113,13 +114,15 @@ describe ActiveRecord::ConnectionHandling do
|
|||
|
||||
context 'when both master and replica server is down' do
|
||||
it 'should raise the right error' do
|
||||
ActiveRecord::Base.expects(:postgresql_connection).with(config).raises(PG::ConnectionBad).once
|
||||
ActiveRecord::Base.expects(:postgresql_connection).with(config).raises(PG::ConnectionBad)
|
||||
|
||||
ActiveRecord::Base.expects(:postgresql_connection).with(config.dup.merge(
|
||||
host: replica_host,
|
||||
port: replica_port
|
||||
)).raises(PG::ConnectionBad).once
|
||||
|
||||
postgresql_fallback_handler.expects(:verify_master).twice
|
||||
|
||||
2.times do
|
||||
expect { ActiveRecord::Base.postgresql_fallback_connection(config) }
|
||||
.to raise_error(PG::ConnectionBad)
|
||||
|
|
|
@ -14,7 +14,7 @@ describe DistributedCache do
|
|||
end
|
||||
|
||||
def cache(name)
|
||||
DistributedCache.new(name, @manager)
|
||||
DistributedCache.new(name, manager: @manager)
|
||||
end
|
||||
|
||||
let! :cache1 do
|
||||
|
|
Loading…
Reference in New Issue