def active?
if @connection.respond_to?(:stat)
@connection.stat
else
@connection.query 'select 1'
end
# mysql-ruby doesn't raise an exception when stat fails.
if @connection.respond_to?(:errno)
@connection.errno.zero?
else
true
end
rescue Mysql::Error
false
end
# Checks whether the connection to the database is still active (i.e. not stale).
# This is done under the hood by calling active?. If the connection
# is no longer active, then this method will reconnect to the database.
def verify!(*ignored)
reconnect! unless active?
end
def checkout_new_connection
c = new_connection
@connections << c
checkout_and_verify(c)
end
def checkout_existing_connection
c = (@connections - @checked_out).first
checkout_and_verify(c)
end
def checkout
# Checkout an available connection
@connection_mutex.synchronize do
loop do
conn = if @checked_out.size < @connections.size
checkout_existing_connection
elsif @connections.size < @size
checkout_new_connection
end
return conn if conn
# No connections available; wait for one
if @queue.wait(@timeout)
next
else
# try looting dead threads
clear_stale_cached_connections!
if @size == @checked_out.size
raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
end
end
end
end
end
# Retrieve the connection associated with the current thread, or call
# #checkout to obtain one if necessary.
#
# #connection can be called any number of times; the connection is
# held in a hash keyed by the thread id.
def connection
if conn = @reserved_connections[current_connection_id]
conn
else
@reserved_connections[current_connection_id] = checkout
end
end
# Signal that the thread is finished with the current connection.
# #release_connection releases the connection-thread association
# and returns the connection to the pool.
def release_connection
conn = @reserved_connections.delete(current_connection_id)
checkin conn if conn
end
# Reserve a connection, and yield it to a block. Ensure the connection is
# checked back in when finished.
def with_connection
conn = checkout
yield conn
ensure
checkin conn
end
とまあだいたいこんな感じで、ActiveRecord::Base.connection.execute("SELECT * FROM users")が実行されるときには、active?メソッドが呼び出されているわけです。実際に、例えばp "Active Check!"なんてのを仕込むと毎回表示されます。これはproduction環境でも変わりませんでした。