aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb12
-rw-r--r--activerecord/test/cases/connection_pool_test.rb15
2 files changed, 27 insertions, 0 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 a88c9e2c4b..3f3b98ace0 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -232,6 +232,18 @@ module ActiveRecord
end
end
+ # Removes dead connections from the pool. A dead connection can occur
+ # if a programmer forgets to close a connection at the end of a thread
+ # or a thread dies unexpectedly.
+ def reap
+ synchronize do
+ stale = Time.now - @timeout
+ connections.dup.each do |conn|
+ remove conn if conn.in_use? && stale > conn.last_use
+ end
+ end
+ end
+
private
def new_connection
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index 10f91d7eb0..015c1c7ce7 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -25,6 +25,21 @@ module ActiveRecord
@pool.connections.each(&:close)
end
+ def test_reap
+ @pool.checkout
+ @pool.checkout
+ @pool.checkout
+ @pool.timeout = 0
+
+ connections = @pool.connections.dup
+
+ @pool.reap
+
+ assert_equal 0, @pool.connections.length
+ ensure
+ connections.map(&:close)
+ end
+
def test_remove_connection
conn = @pool.checkout
assert conn.in_use?