class ReplicaPools::ConnectionProxy
Attributes
current[RW]
current_pool[RW]
leader[RW]
leader_depth[RW]
replica_pools[RW]
Public Class Methods
generate_safe_delegations()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 12 def generate_safe_delegations ReplicaPools.config.safe_methods.each do |method| self.define_method(method) do |*args, &block| route_to(current, method, *args, &block) end unless instance_methods.include?(method) end end
get_connection_config_method_name()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 39 def self.get_connection_config_method_name # 6.1 supports current.connection_config # but warns of impending deprecation in 6.2 if ActiveRecord::VERSION::STRING.to_f >= 6.1 :connection_db_config else :connection_config end end
new(leader, pools)
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 21 def initialize(leader, pools) @leader = leader @replica_pools = pools @leader_depth = 0 @current_pool = default_pool if ReplicaPools.config.defaults_to_leader @current = leader else @current = current_replica end # this ivar is for ConnectionAdapter compatibility # some gems (e.g. newrelic_rpm) will actually use # instance_variable_get(:@config) to find it. @config = current.send(ReplicaPools::ConnectionProxy.get_connection_config_method_name) end
Public Instance Methods
current_replica()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 82 def current_replica current_pool.current end
next_replica!()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 77 def next_replica! return if within_leader_block? self.current = current_pool.next end
transaction(...)
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 73 def transaction(...) with_leader { leader.transaction(...) } end
with_leader() { || ... }
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 59 def with_leader raise LeaderDisabled.new if ReplicaPools.config.disable_leader last_conn = self.current self.current = leader self.leader_depth += 1 yield ensure if last_conn self.leader_depth = [leader_depth - 1, 0].max self.current = last_conn end end
with_pool(pool_name = 'default') { || ... }
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 49 def with_pool(pool_name = 'default') last_conn, last_pool = self.current, self.current_pool self.current_pool = replica_pools[pool_name.to_sym] || default_pool self.current = current_replica unless within_leader_block? yield ensure self.current_pool = last_pool self.current = last_conn end
Protected Instance Methods
default_pool()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 88 def default_pool replica_pools[:default] || replica_pools.values.first end
method_missing(method, *args, **kwargs, &block)
click to toggle source
Proxies any unknown methods to leader. Safe methods have been generated during ‘setup!`. Creates a method to speed up subsequent calls.
# File lib/replica_pools/connection_proxy.rb, line 95 def method_missing(method, *args, **kwargs, &block) self.class.define_method(method) do |*args, **kwargs, &block| route_to(leader, method, *args, **kwargs, &block).tap do if %i[insert delete update].include?(method) leader.retrieve_connection.clear_query_cache end end end send(method, *args, **kwargs, &block) end
route_to(conn, method, *args, **keyword_args, &block)
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 110 def route_to(conn, method, *args, **keyword_args, &block) raise ReplicaPools::LeaderDisabled.new if ReplicaPools.config.disable_leader && conn == leader conn.retrieve_connection.send(method, *args, **keyword_args, &block) rescue => e ReplicaPools.log :error, "Error during ##{method}: #{e}" log_proxy_state raise e end
within_leader_block?()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 106 def within_leader_block? leader_depth > 0 end
Private Instance Methods
log_proxy_state()
click to toggle source
# File lib/replica_pools/connection_proxy.rb, line 121 def log_proxy_state ReplicaPools.log :error, "Current Connection: #{current}" ReplicaPools.log :error, "Current Pool Name: #{current_pool.name}" ReplicaPools.log :error, "Current Pool Members: #{current_pool.replicas}" ReplicaPools.log :error, "Leader Depth: #{leader_depth}" end