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