mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Fix race in ConnectionPool#checkout
After releasing monitor some connection(s) may appear in pool before monitor is re-aquired. When this happens we'll wait for connection which is already available. Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
committed by
Michael Koziarski
parent
4cb3d27443
commit
21eb18a70c
@@ -131,21 +131,20 @@ module ActiveRecord
|
||||
# Check-out a database connection from the pool.
|
||||
def checkout
|
||||
# Checkout an available connection
|
||||
conn = @connection_mutex.synchronize do
|
||||
if @checked_out.size < @connections.size
|
||||
checkout_existing_connection
|
||||
elsif @connections.size < @size
|
||||
checkout_new_connection
|
||||
end
|
||||
end
|
||||
return conn if conn
|
||||
|
||||
# No connections available; wait for one
|
||||
@connection_mutex.synchronize do
|
||||
if @queue.wait(@timeout)
|
||||
checkout_existing_connection
|
||||
else
|
||||
raise ConnectionTimeoutError, "could not obtain a database connection within #{@timeout} seconds. The pool size is currently #{@size}, perhaps you need to increase it?"
|
||||
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
|
||||
raise ConnectionTimeoutError, "could not obtain a database connection within #{@timeout} seconds. The pool size is currently #{@size}, perhaps you need to increase it?"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -275,4 +274,4 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user