@@ -455,43 +455,63 @@ def test_disconnect_and_clear_reloadable_connections_are_able_to_preempt_other_w
455455 with_single_connection_pool do |pool |
456456 [ :disconnect , :disconnect! , :clear_reloadable_connections , :clear_reloadable_connections! ] . each do |group_action_method |
457457 conn = pool . connection # drain the only available connection
458- second_thread_done = Concurrent ::CountDownLatch . new
458+ second_thread_done = Concurrent ::Event . new
459459
460- # create a first_thread and let it get into the FIFO queue first
461- first_thread = Thread . new do
462- pool . with_connection { second_thread_done . wait }
463- end
464-
465- # wait for first_thread to get in queue
466- Thread . pass until pool . num_waiting_in_queue == 1
467-
468- # create a different, later thread, that will attempt to do a "group action",
469- # but because of the group action semantics it should be able to preempt the
470- # first_thread when a connection is made available
471- second_thread = Thread . new do
472- pool . send ( group_action_method )
473- second_thread_done . count_down
460+ begin
461+ # create a first_thread and let it get into the FIFO queue first
462+ first_thread = Thread . new do
463+ pool . with_connection { second_thread_done . wait }
464+ end
465+
466+ # wait for first_thread to get in queue
467+ Thread . pass until pool . num_waiting_in_queue == 1
468+
469+ # create a different, later thread, that will attempt to do a "group action",
470+ # but because of the group action semantics it should be able to preempt the
471+ # first_thread when a connection is made available
472+ second_thread = Thread . new do
473+ pool . send ( group_action_method )
474+ second_thread_done . set
475+ end
476+
477+ # wait for second_thread to get in queue
478+ Thread . pass until pool . num_waiting_in_queue == 2
479+
480+ # return the only available connection
481+ pool . checkin ( conn )
482+
483+ # if the second_thread is not able to preempt the first_thread,
484+ # they will temporarily (until either of them timeouts with ConnectionTimeoutError)
485+ # deadlock and a join(2) timeout will be reached
486+ assert second_thread . join ( 2 ) , "#{ group_action_method } is not able to preempt other waiting threads"
487+
488+ ensure
489+ # post test clean up
490+ failed = !second_thread_done . set?
491+
492+ if failed
493+ second_thread_done . set
494+
495+ puts
496+ puts ">>> test_disconnect_and_clear_reloadable_connections_are_able_to_preempt_other_waiting_threads / #{ group_action_method } "
497+ p [ first_thread , second_thread ]
498+ p pool . stat
499+ p pool . connections . map ( &:owner )
500+
501+ first_thread . join ( 2 )
502+ second_thread . join ( 2 )
503+
504+ puts '---'
505+ p [ first_thread , second_thread ]
506+ p pool . stat
507+ p pool . connections . map ( &:owner )
508+ puts '<<<'
509+ puts
510+ end
511+
512+ first_thread . join ( 10 ) || raise ( "first_thread got stuck" )
513+ second_thread . join ( 10 ) || raise ( "second_thread got stuck" )
474514 end
475-
476- # wait for second_thread to get in queue
477- Thread . pass until pool . num_waiting_in_queue == 2
478-
479- # return the only available connection
480- pool . checkin ( conn )
481-
482- # if the second_thread is not able to preempt the first_thread,
483- # they will temporarily (until either of them timeouts with ConnectionTimeoutError)
484- # deadlock and a join(2) timeout will be reached
485- failed = true unless second_thread . join ( 2 )
486-
487- #--- post test clean up start
488- second_thread_done . count_down if failed
489-
490- first_thread . join
491- second_thread . join
492- #--- post test clean up end
493-
494- flunk "#{ group_action_method } is not able to preempt other waiting threads" if failed
495515 end
496516 end
497517 end
0 commit comments