Check-out a database connection
from the pool, indicating that you want to use it. You should call #checkin
when you no longer need this.
This is done by either returning an existing connection, or by creating a
newconnection.
If the maximum number of connections for this pool has already been
reached, but the pool is empty (i.e. they’re all being used), then this
method will wait until a thread has checked in a connection.
The wait time is bounded however: if no connection
can be checked out within the timeout specified for this pool, then a
ConnectionTimeoutError exception will be raised.
ConnectionTimeoutError: no connection
can be obtained from the pool within the timeout period.
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 232
def checkout
synchronize do
waited_time = 0
loop do
conn = @connections.find { |c| c.lease }
unless conn
if @connections.size < @size
conn = checkout_new_connection
conn.lease
end
end
if conn
checkout_and_verify conn
return conn
end
if waited_time >= @timeout
raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout} (waited #{waited_time} seconds). The max pool size is currently #{@size}; consider increasing it."
end
# Sometimes our wait can end because a connection is available,
# but another thread can snatch it up first. If timeout hasn't
# passed but no connection is avail, looks like that happened --
# loop and wait again, for the time remaining on our timeout.
before_wait = Time.now
@queue.wait( [@timeout - waited_time, 0].max )
waited_time += (Time.now - before_wait)
# Will go away in Rails 4, when we don't clean up
# after leaked connections automatically anymore. Right now, clean
# up after we've returned from a 'wait' if it looks like it's
# needed, then loop and try again.
if(active_connections.size >= @connections.size)
clear_stale_cached_connections!
end
end
end
end