From b72b477c373b54200bfc49c8c0b0f9e42e7e68e3 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Nov 2011 13:40:27 -0800 Subject: [PATCH] Use connection lease to determine "checked_out" connections --- .../abstract/connection_pool.rb | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 0c64ffdeaf..260d58b2e0 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -82,7 +82,6 @@ def initialize(spec) @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5 @connections = [] - @checked_out = [] @automatic_reconnect = true end @@ -216,20 +215,27 @@ 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 + 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 @queue.wait(@timeout) - if(@checked_out.size < @connections.size) + if(checked_out.size < @connections.size) next else clear_stale_cached_connections! - if @size == @checked_out.size + 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 @@ -246,7 +252,7 @@ def checkout def checkin(conn) @connection_mutex.synchronize do conn.run_callbacks :checkin do - @checked_out.delete conn + conn.expire @queue.signal end end @@ -270,21 +276,19 @@ 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) + c end def checkout_and_verify(c) c.run_callbacks :checkout do c.verify! - @checked_out << c end c end + + def checked_out + @connections.find_all { |c| c.in_use? } + end end # ConnectionHandler is a collection of ConnectionPool objects. It is used -- GitLab