# File lib/rails_failover/active_record/handler.rb, line 30 def primary_down?(handler_key) primaries_down[handler_key] end
class RailsFailover::ActiveRecord::Handler
Constants
- VERIFY_FREQUENCY_BUFFER_PRECENT
Public Class Methods
new()
click to toggle source
Calls superclass method
# File lib/rails_failover/active_record/handler.rb, line 14 def initialize @primaries_down = Concurrent::Map.new super() # Monitor#initialize end
Public Instance Methods
primaries_down_count()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 34 def primaries_down_count primaries_down.size end
primary_down?(handler_key)
click to toggle source
verify_primary(handler_key)
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 20 def verify_primary(handler_key) primary_down(handler_key) mon_synchronize do return if @thread&.alive? logger.warn "Failover for ActiveRecord has been initiated" @thread = Thread.new { loop_until_all_up } end end
Private Instance Methods
all_primaries_up()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 91 def all_primaries_up primaries_down.empty? end
initiate_fallback_to_primary()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 51 def initiate_fallback_to_primary frequency = RailsFailover::ActiveRecord.verify_primary_frequency_seconds sleep(frequency * ((rand(VERIFY_FREQUENCY_BUFFER_PRECENT) + 100) / 100.0)) active_handler_keys = [] primaries_down.keys.each do |handler_key| connection_handler = ::ActiveRecord::Base.connection_handlers[handler_key] connection_pool = connection_handler.retrieve_connection_pool(spec_name) if connection_pool.respond_to?(:db_config) config = connection_pool.db_config.configuration_hash adapter_method = connection_pool.db_config.adapter_method else config = connection_pool.spec.config adapter_method = connection_pool.spec.adapter_method end logger.debug "#{Process.pid} Checking server for '#{handler_key} #{spec_name}'..." connection_active = false begin connection = ::ActiveRecord::Base.public_send(adapter_method, config) connection_active = connection.active? rescue => e logger.debug "#{Process.pid} Connection to server for '#{handler_key} #{spec_name}' failed with '#{e.message}'" ensure connection.disconnect! if connection end if connection_active logger.debug "#{Process.pid} Server for '#{handler_key} #{spec_name}' is active." active_handler_keys << handler_key end end active_handler_keys.each do |handler_key| primary_up(handler_key) end end
logger()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 123 def logger ::Rails.logger end
loop_until_all_up()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 40 def loop_until_all_up loop do initiate_fallback_to_primary if all_primaries_up logger.warn "Fallback to primary for ActiveRecord has been completed." break end end end
primaries_down()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 109 def primaries_down ancestor_pids = nil value = @primaries_down.compute_if_absent(Process.pid) do ancestor_pids = @primaries_down.keys @primaries_down.values.first || Concurrent::Map.new end ancestor_pids&.each do |pid| @primaries_down.delete(pid)&.each_key { |key| verify_primary(key) } end value end
primary_down(handler_key)
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 95 def primary_down(handler_key) already_down = primaries_down.put_if_absent(handler_key, true) RailsFailover::ActiveRecord.on_failover_callback!(handler_key) if !already_down end
primary_up(handler_key)
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 100 def primary_up(handler_key) already_up = !primaries_down.delete(handler_key) RailsFailover::ActiveRecord.on_fallback_callback!(handler_key) if !already_up end
spec_name()
click to toggle source
# File lib/rails_failover/active_record/handler.rb, line 105 def spec_name ::ActiveRecord::Base.connection_specification_name end