class SlavePools::ConnectionProxy

Attributes

current[RW]
current_pool[RW]
master[RW]
master_depth[RW]
slave_pools[RW]

Public Class Methods

generate_safe_delegations() click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 12
def generate_safe_delegations
  SlavePools.config.safe_methods.each do |method|
    generate_safe_delegation(method) unless instance_methods.include?(method)
  end
end
new(master, pools) click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 29
def initialize(master, pools)
  @master       = master
  @slave_pools  = pools
  @master_depth = 0
  @current_pool = default_pool

  if SlavePools.config.defaults_to_master
    @current = master
  else
    @current = current_slave
  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.connection_config
end

Protected Class Methods

generate_safe_delegation(method) click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 20
      def generate_safe_delegation(method)
        class_eval <<-END, __FILE__, __LINE__ + 1
          def #{method}(*args, &block)
            route_to(current, :#{method}, *args, &block)
          end
        END
      end

Public Instance Methods

current_slave() click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 76
def current_slave
  current_pool.current
end
next_slave!() click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 71
def next_slave!
  return if within_master_block?
  self.current = current_pool.next
end
transaction(*args, &block) click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 67
def transaction(*args, &block)
  with_master { master.transaction(*args, &block) }
end
with_master() { || ... } click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 57
def with_master
  last_conn = self.current
  self.current = master
  self.master_depth += 1
  yield
ensure
  self.master_depth = [master_depth - 1, 0].max
  self.current = last_conn
end
with_pool(pool_name = 'default') { || ... } click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 47
def with_pool(pool_name = 'default')
  last_conn, last_pool = self.current, self.current_pool
  self.current_pool = slave_pools[pool_name.to_sym] || default_pool
  self.current = current_slave unless within_master_block?
  yield
ensure
  self.current_pool = last_pool
  self.current      = last_conn
end

Protected Instance Methods

default_pool() click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 82
def default_pool
  slave_pools[:default] || slave_pools.values.first
end
generate_unsafe_delegation(method) click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 98
    def generate_unsafe_delegation(method)
      self.class_eval <<-END, __FILE__, __LINE__ + 1
        def #{method}(*args, &block)
          route_to(master, :#{method}, *args, &block)
        end
      END
    end
method_missing(method, *args, &block) click to toggle source

Proxies any unknown methods to master. Safe methods have been generated during `setup!`. Creates a method to speed up subsequent calls.

# File lib/slave_pools/connection_proxy.rb, line 89
def method_missing(method, *args, &block)
  generate_unsafe_delegation(method)
  send(method, *args, &block)
end
route_to(conn, method, *args, &block) click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 106
def route_to(conn, method, *args, &block)
  conn.retrieve_connection.send(method, *args, &block)
rescue => e
  SlavePools.log :error, "Error during ##{method}: #{e}"
  log_proxy_state

  current.retrieve_connection.verify! # may reconnect
  raise e
end
within_master_block?() click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 94
def within_master_block?
  master_depth > 0
end

Private Instance Methods

log_proxy_state() click to toggle source
# File lib/slave_pools/connection_proxy.rb, line 118
def log_proxy_state
  SlavePools.log :error, "Current Connection: #{current}"
  SlavePools.log :error, "Current Pool Name: #{current_pool.name}"
  SlavePools.log :error, "Current Pool Members: #{current_pool.slaves}"
  SlavePools.log :error, "Master Depth: #{master_depth}"
end