Skip to content

Commit 3b13761

Browse files
authored
Merge pull request rails#27108 from matthewd/allocate-connections-after-blocking
Distribute connections to previously blocked threads when we're done
2 parents 33039fa + d314646 commit 3b13761

File tree

2 files changed

+17
-25
lines changed

2 files changed

+17
-25
lines changed

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

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@ def disconnect(raise_on_acquisition_timeout = true)
422422
conn.disconnect!
423423
end
424424
@connections = []
425-
@available.clear
426425
end
427426
end
428427
end
@@ -445,8 +444,6 @@ def disconnect!
445444
# connections in the pool within a timeout interval (default duration is
446445
# <tt>spec.config[:checkout_timeout] * 2</tt> seconds).
447446
def clear_reloadable_connections(raise_on_acquisition_timeout = true)
448-
num_new_conns_required = 0
449-
450447
with_exclusively_acquired_all_connections(raise_on_acquisition_timeout) do
451448
synchronize do
452449
@connections.each do |conn|
@@ -457,24 +454,8 @@ def clear_reloadable_connections(raise_on_acquisition_timeout = true)
457454
conn.disconnect! if conn.requires_reloading?
458455
end
459456
@connections.delete_if(&:requires_reloading?)
460-
461-
@available.clear
462-
463-
if @connections.size < @size
464-
# because of the pruning done by this method, we might be running
465-
# low on connections, while threads stuck in queue are helpless
466-
# (not being able to establish new connections for themselves),
467-
# see also more detailed explanation in +remove+
468-
num_new_conns_required = num_waiting_in_queue - @connections.size
469-
end
470-
471-
@connections.each do |conn|
472-
@available.add conn
473-
end
474457
end
475458
end
476-
477-
bulk_make_new_connections(num_new_conns_required) if num_new_conns_required > 0
478459
end
479460

480461
# Clears the cache which maps classes and re-connects connections that
@@ -705,9 +686,26 @@ def with_new_connections_blocked
705686

706687
yield
707688
ensure
689+
num_new_conns_required = 0
690+
708691
synchronize do
709692
@threads_blocking_new_connections -= 1
693+
694+
if @threads_blocking_new_connections.zero?
695+
@available.clear
696+
697+
num_new_conns_required = num_waiting_in_queue
698+
699+
@connections.each do |conn|
700+
next if conn.in_use?
701+
702+
@available.add conn
703+
num_new_conns_required -= 1
704+
end
705+
end
710706
end
707+
708+
bulk_make_new_connections(num_new_conns_required) if num_new_conns_required > 0
711709
end
712710

713711
# Acquire a connection by one of 1) immediately removing one

activerecord/test/cases/connection_pool_test.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,12 +487,6 @@ def test_disconnect_and_clear_reloadable_connections_are_able_to_preempt_other_w
487487
#--- post test clean up start
488488
second_thread_done.count_down if failed
489489

490-
# after `pool.disconnect()` the first thread will be left stuck in queue, no need to wait for
491-
# it to timeout with ConnectionTimeoutError
492-
if (group_action_method == :disconnect || group_action_method == :disconnect!) && pool.num_waiting_in_queue > 0
493-
pool.with_connection {} # create a new connection in case there are threads still stuck in a queue
494-
end
495-
496490
first_thread.join
497491
second_thread.join
498492
#--- post test clean up end

0 commit comments

Comments
 (0)