Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #5423 from jrochkind/checkout_account_for_monitor_…

…model

ConnectionPool.checkout needs to be restructured to take account of ruby's "non-blocking" strategy for mutex ConditionVariables
  • Loading branch information...
commit f2aea24d3b2c3aeabdab5ead632d68b97c76aa58 2 parents 596ecf7 + 41563b4
@tenderlove tenderlove authored
View
27 activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -226,8 +226,9 @@ def clear_stale_cached_connections!
# - ConnectionTimeoutError: no connection can be obtained from the pool
# within the timeout period.
def checkout
- # Checkout an available connection
synchronize do
+ waited_time = 0
+
loop do
conn = @connections.find { |c| c.lease }
@@ -243,17 +244,25 @@ def checkout
return conn
end
- @queue.wait(@timeout)
+ 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
- if(active_connections.size < @connections.size)
- next
- else
+ # 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!
- if @size == active_connections.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
Please sign in to comment.
Something went wrong with that request. Please try again.