Skip to content

Commit c80fa6a

Browse files
authored
Merge pull request rails#50190 from jhawthorn/retry_checkout_after_reap
Retry new connection on checkout after reap
2 parents 71c7313 + afefa50 commit c80fa6a

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,13 @@ def acquire_connection(checkout_timeout)
668668
conn
669669
else
670670
reap
671-
@available.poll(checkout_timeout)
671+
# Retry after reaping, which may return an available connection,
672+
# remove an inactive connection, or both
673+
if conn = @available.poll || try_to_checkout_new_connection
674+
conn
675+
else
676+
@available.poll(checkout_timeout)
677+
end
672678
end
673679
rescue ConnectionTimeoutError => ex
674680
raise ex.set_pool(self)

activerecord/test/cases/connection_pool_test.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,30 @@ def test_reap_inactive
216216
@pool.connections.each { |conn| conn.close if conn.in_use? }
217217
end
218218

219+
def test_inactive_are_returned_from_dead_thread
220+
ready = Concurrent::CountDownLatch.new
221+
@pool.instance_variable_set(:@size, 1)
222+
223+
child = new_thread do
224+
@pool.checkout
225+
ready.count_down
226+
stop_thread
227+
end
228+
229+
pass_to(child) until ready.wait(0)
230+
231+
assert_equal 1, active_connections(@pool).size
232+
233+
child.terminate
234+
child.join
235+
236+
@pool.checkout
237+
238+
assert_equal 1, active_connections(@pool).size
239+
ensure
240+
@pool.connections.each { |conn| conn.close if conn.in_use? }
241+
end
242+
219243
def test_idle_timeout_configuration
220244
@pool.disconnect!
221245

0 commit comments

Comments
 (0)