Created
May 11, 2012 09:48
-
-
Save cris/2658680 to your computer and use it in GitHub Desktop.
Fix for broken connection-pool in Rails < 3.3.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Monkey patch ConnectionPool#checkout to avoid database connection timeouts | |
# Source: https://github.com/rails/rails/issues/2547 | |
# For Rails 3.2.0 and upper, You need to check if the pool error still occurs | |
if Rails.version < "3.3.0" | |
class ActiveRecord::ConnectionAdapters::ConnectionPool | |
def checkout | |
# Checkout an available connection | |
start_at = Time.now | |
@connection_mutex.synchronize do | |
loop do | |
conn = try_to_obtain_connection | |
return conn if conn | |
should_not_be_timeout!(start_at) | |
# No connections available; wait for one | |
is_timeout = !@queue.wait(@timeout) # mutex is lost | |
# mutex is obtained again | |
if is_timeout | |
# try looting dead threads | |
clear_stale_cached_connections! | |
raise_timeout_error! unless can_obtain_connection? | |
end | |
end | |
end | |
end | |
synchronize :connection, :release_connection, :clear_stale_cached_connections!, :with => :@connection_mutex | |
private | |
def can_obtain_connection? | |
@size > @checked_out.size | |
end | |
def should_not_be_timeout!(start_at) | |
return if (Time.now - start_at) < @timeout | |
raise_timeout_error! | |
end | |
def try_to_obtain_connection | |
if @checked_out.size < @connections.size | |
checkout_existing_connection | |
elsif @connections.size < @size | |
checkout_new_connection | |
end | |
end | |
def raise_timeout_error! | |
raise ActiveRecord::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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment