class Postamt::ConnectionHandler

Public Class Methods

new() click to toggle source
# File lib/postamt/connection_handler.rb, line 5
def initialize
  @process_pid = ThreadSafe::Util::AtomicReference.new(nil)
end

Public Instance Methods

active_connections?() click to toggle source

Returns true if there are any active connections among the connection pools that the ConnectionHandler is managing.

# File lib/postamt/connection_handler.rb, line 21
def active_connections?
  self.ensure_ready
  self.connection_pool_list.any?(&:active_connection?)
end
clear_active_connections!() click to toggle source

Returns any connections in use by the current thread back to the pool, and also returns connections to the pool cached by threads that are no longer alive.

# File lib/postamt/connection_handler.rb, line 29
def clear_active_connections!
  self.ensure_ready
  self.connection_pool_list.each(&:release_connection)
end
clear_all_connections!() click to toggle source
# File lib/postamt/connection_handler.rb, line 40
def clear_all_connections!
  self.ensure_ready
  self.connection_pool_list.each(&:disconnect!)
end
clear_reloadable_connections!() click to toggle source

Clears the cache which maps classes.

# File lib/postamt/connection_handler.rb, line 35
def clear_reloadable_connections!
  self.ensure_ready
  self.connection_pool_list.each(&:clear_reloadable_connections!)
end
connected?(klass) click to toggle source

Returns true if a connection that's accessible to this class has already been opened.

# File lib/postamt/connection_handler.rb, line 57
def connected?(klass)
  return false if Process.pid != @process_pid.get
  conn = self.retrieve_connection_pool(klass)
  conn && conn.connected?
end
connection_pool_list() click to toggle source
# File lib/postamt/connection_handler.rb, line 14
def connection_pool_list
  self.ensure_ready
  @pools.values
end
connection_pools() click to toggle source
# File lib/postamt/connection_handler.rb, line 9
def connection_pools
  # See https://github.com/rails/rails/commit/c3ca7ac09e960fa1287adc730e8ddc713e844c37
  Hash[self.connection_pool_list.map { |pool| [pool.spec, pool] }]
end
remove_connection(owner) click to toggle source

Only called in ActiveRecord test code, so performance isn't an issue.

# File lib/postamt/connection_handler.rb, line 64
def remove_connection(owner)
  self.clear_cache
  # Don't return a ConnectionSpecification hash since we've disabled establish_connection anyway
  return nil
end
retrieve_connection_pool(klass) click to toggle source

Called by ActiveRecord::ConnectionHandling#connection_pool.

# File lib/postamt/connection_handler.rb, line 71
def retrieve_connection_pool(klass)
  self.ensure_ready
  self.pool_for(klass)
end

Protected Instance Methods

clear_cache() click to toggle source

Throw away all pools on next request

# File lib/postamt/connection_handler.rb, line 91
def clear_cache
  @process_pid.set(nil)
end
connection_for(klass) click to toggle source
# File lib/postamt/connection_handler.rb, line 95
def connection_for(klass)
  Postamt.force_connection || Postamt.connection_stack.last || Postamt.overwritten_default_connections[klass.name] || klass.default_connection || Postamt.default_connection
end
ensure_ready() click to toggle source
# File lib/postamt/connection_handler.rb, line 83
def ensure_ready
  if Process.pid != @process_pid.get
    # We've been forked -> throw away connection pools
    prepare
  end
end
pool_for(klass) click to toggle source
# File lib/postamt/connection_handler.rb, line 99
def pool_for(klass)
  # Sauspiel's reportable dependency makes Rails 3.2 request a connection early,
  # before the App is initialized. Return nil in that case, Rails deals with that
  return nil if ActiveRecord::Base.configurations[Rails.env].nil?

  connection = connection_for(klass)
  # Ideally we would use #fetch here, as class_to_pool[klass] may sometimes be nil.
  # However, benchmarking (https://gist.github.com/jonleighton/3552829) showed that
  # #fetch is significantly slower than #[]. So in the nil case, no caching will
  # take place, but that's ok since the nil case is not the common one that we wish
  # to optimise for.
  @pools[connection] ||= begin
    Postamt.configurations[connection.to_s] ||= Postamt.configurations['master']

    spec = if Rails::VERSION::MAJOR == 4 and Rails::VERSION::MINOR <= 2
      resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new Postamt.configurations
      resolver.spec(connection)
    elsif Rails::VERSION::MAJOR == 4 and Rails::VERSION::MINOR == 0
      resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new connection, Postamt.configurations
      resolver.spec
    elsif Rails::VERSION::MAJOR == 3 and Rails::VERSION::MINOR == 2
      resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new connection, Postamt.configurations
      resolver.spec
    else
      abort "Postamt doesn't support Rails version #{Rails.version}"
    end

    unless ActiveRecord::Base.respond_to?(spec.adapter_method)
      raise ActiveRecord::AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
    end

    ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
  end
end
prepare() click to toggle source
# File lib/postamt/connection_handler.rb, line 78
def prepare
  @process_pid.set(Process.pid)
  @pools = ThreadSafe::Cache.new(initial_capacity: 2)
end