class ActiveRecord::ConnectionAdapters::ConnectionPool

5 seconds).
after which the Reaper will consider a connection reapable. (default
* dead_connection_timeout: number of seconds from last checkout
run the Reaper).
thread or a thread dies unexpectedly. (Default nil, which means don’t
occur if a programmer forgets to close a connection at the end of a
Reaper, which attempts to find and close dead connections, which can
* reaping_frequency: frequency in seconds to periodically run the
before giving up and raising a timeout error (default 5 seconds).
* checkout_timeout: number of seconds to block and wait for a connection
* pool: number indicating size of connection pool (default 5)
your database connection configuration:
There are several connection-pooling-related options that you can add to
== Options
compatible with AbstractAdapter’s interface).
Connections in the pool are actually AbstractAdapter objects (or objects
and returns it to the pool after the block completes.
obtains a connection, yields it as the sole argument to the block,
3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which
ActiveRecord::Base.connection_pool.checkin(connection).
returning this connection to the pool when finished by calling
ActiveRecord::Base.connection_pool.checkout. You are responsible for
2. Manually check out a connection from the pool with
Action Pack’s request handling cycle.
default behavior for Active Record when used in conjunction with
ActiveRecord::Base.clear_active_connections!. This will be the
the connection(s) and wish it to be returned to the pool, you call
earlier (pre-connection-pooling). Eventually, when you’re done with
1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and
ways:
Connections can be obtained and used from a connection pool in several
== Obtaining (checking out) a connection
has checked in a connection.
connection anyway, then ConnectionPool will wait until some other thread
connections have been checked out, and a thread tries to checkout a
handle cases in which there are more threads than connections: if all
as long as ConnectionPool’s contract is correctly followed. It will also
ensure that a connection cannot be used by two threads at the same time,
connection back in. ConnectionPool is completely thread-safe, and will
database connection from the pool, uses that connection, and checks the
database connections. The basic idea is that each thread checks out a
A connection pool synchronizes thread access to a limited number of
== Introduction
connections.
Connection pool base class for managing Active Record database

def acquire_connection

- ConnectionTimeoutError if a connection could not be acquired
Raises:

queue for a connection to become available.
connection if the pool is not at capacity, 3) waiting on the
from the queue of available connections, 2) creating a new
Acquire a connection by one of 1) immediately removing one
def acquire_connection
  if conn = @available.poll
    conn
  elsif @connections.size < @size
    checkout_new_connection
  else
    @available.poll(@checkout_timeout)
  end
end

def active_connection?

Is there an open connection that is being used for the current thread?
def active_connection?
  synchronize do
    @reserved_connections.fetch(current_connection_id) {
      return false
    }.in_use?
  end
end

def checkin(conn)

calling +checkout+ on this pool.
+conn+: an AbstractAdapter object, which was obtained by earlier by

no longer need this connection.
Check-in a database connection back into the pool, indicating that you
def checkin(conn)
  synchronize do
    conn.run_callbacks :checkin do
      conn.expire
    end
    release conn
    @available.add conn
  end
end

def checkout

- ConnectionTimeoutError: no connection can be obtained from the pool.
Raises:

Returns: an AbstractAdapter object.

size limit set), an ActiveRecord::ConnectionTimeoutError exception will be raised.
number of currently leased connections is greater than or equal to the
If all connections are leased and the pool is at capacity (meaning the

creating a new connection and leasing it.
This is done by either returning and leasing existing connection, or by

to use it. You should call #checkin when you no longer need this.
Check-out a database connection from the pool, indicating that you want
def checkout
  synchronize do
    conn = acquire_connection
    conn.lease
    checkout_and_verify(conn)
  end
end

def checkout_and_verify(c)

def checkout_and_verify(c)
  c.run_callbacks :checkout do
    c.verify!
  end
  c
end

def checkout_new_connection

def checkout_new_connection
  raise ConnectionNotEstablished unless @automatic_reconnect
  c = new_connection
  c.pool = self
  @connections << c
  c
end

def clear_reloadable_connections!

Clears the cache which maps classes.
def clear_reloadable_connections!
  synchronize do
    @reserved_connections.clear
    @connections.each do |conn|
      checkin conn
      conn.disconnect! if conn.requires_reloading?
    end
    @connections.delete_if do |conn|
      conn.requires_reloading?
    end
    @available.clear
    @connections.each do |conn|
      @available.add conn
    end
  end
end

def clear_stale_cached_connections! # :nodoc:

:nodoc:
def clear_stale_cached_connections! # :nodoc:
  reap
end

def connected?

Returns true if a connection has already been opened.
def connected?
  synchronize { @connections.any? }
end

def connection

held in a hash keyed by the thread id.
#connection can be called any number of times; the connection is

#checkout to obtain one if necessary.
Retrieve the connection associated with the current thread, or call
def connection
  # this is correctly done double-checked locking
  # (ThreadSafe::Cache's lookups have volatile semantics)
  @reserved_connections[current_connection_id] || synchronize do
    @reserved_connections[current_connection_id] ||= checkout
  end
end

def current_connection_id #:nodoc:

:nodoc:
def current_connection_id #:nodoc:
  Base.connection_id ||= Thread.current.object_id
end

def disconnect!

Disconnects all connections in the pool, and clears the pool.
def disconnect!
  synchronize do
    @reserved_connections.clear
    @connections.each do |conn|
      checkin conn
      conn.disconnect!
    end
    @connections = []
    @available.clear
  end
end

def initialize(spec)

The default ConnectionPool maximum size is 5.

this ConnectionPool.
host name, username, password, etc), as well as the maximum size for
object which describes database connection information (e.g. adapter,
Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
def initialize(spec)
  super()
  @spec = spec
  @checkout_timeout = spec.config[:checkout_timeout] || 5
  @dead_connection_timeout = spec.config[:dead_connection_timeout] || 5
  @reaper  = Reaper.new self, spec.config[:reaping_frequency]
  @reaper.run
  # default max pool size to 5
  @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
  # The cache of reserved connections mapped to threads
  @reserved_connections = ThreadSafe::Cache.new(:initial_capacity => @size)
  @connections         = []
  @automatic_reconnect = true
  @available = Queue.new self
end

def new_connection

def new_connection
  Base.send(spec.adapter_method, spec.config)
end

def reap

or a thread dies unexpectedly.
if a programmer forgets to close a connection at the end of a thread
Removes dead connections from the pool. A dead connection can occur
def reap
  synchronize do
    stale = Time.now - @dead_connection_timeout
    connections.dup.each do |conn|
      if conn.in_use? && stale > conn.last_use && !conn.active?
        remove conn
      end
    end
  end
end

def release(conn)

def release(conn)
  thread_id = if @reserved_connections[current_connection_id] == conn
    current_connection_id
  else
    @reserved_connections.keys.find { |k|
      @reserved_connections[k] == conn
    }
  end
  @reserved_connections.delete thread_id if thread_id
end

def release_connection(with_id = current_connection_id)

and returns the connection to the pool.
#release_connection releases the connection-thread association
Signal that the thread is finished with the current connection.
def release_connection(with_id = current_connection_id)
  synchronize do
    conn = @reserved_connections.delete(with_id)
    checkin conn if conn
  end
end

def remove(conn)

remain open and active but will no longer be managed by this pool.
Remove a connection from the connection pool. The connection will
def remove(conn)
  synchronize do
    @connections.delete conn
    @available.delete conn
    # FIXME: we might want to store the key on the connection so that removing
    # from the reserved hash will be a little easier.
    release conn
    @available.add checkout_new_connection if @available.any_waiting?
  end
end

def with_connection

connection when finished.
exists checkout a connection, yield it to the block, and checkin the
If a connection already exists yield it to the block. If no connection
def with_connection
  connection_id = current_connection_id
  fresh_connection = true unless active_connection?
  yield connection
ensure
  release_connection(connection_id) if fresh_connection
end