From 87f5e5e28a4b52f548451a4e4e232e9449ed3b7b Mon Sep 17 00:00:00 2001
From: Matthew Draper <matthew@trebex.net>
Date: Sat, 26 Nov 2016 15:35:23 +1030
Subject: Make the test that seems to be getting stuck noisier

I assume it's upset because of the change in d314646c965b045724e6bdb9d61dcecfabc0ba8f,
but I don't yet understand why.
---
 activerecord/test/cases/connection_pool_test.rb | 90 +++++++++++++++----------
 1 file changed, 55 insertions(+), 35 deletions(-)

(limited to 'activerecord')

diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index 2437c99621..1d4cd3c78b 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -455,43 +455,63 @@ module ActiveRecord
         with_single_connection_pool do |pool|
           [:disconnect, :disconnect!, :clear_reloadable_connections, :clear_reloadable_connections!].each do |group_action_method|
             conn               = pool.connection # drain the only available connection
-            second_thread_done = Concurrent::CountDownLatch.new
+            second_thread_done = Concurrent::Event.new
 
-            # create a first_thread and let it get into the FIFO queue first
-            first_thread = Thread.new do
-              pool.with_connection { second_thread_done.wait }
-            end
-
-            # wait for first_thread to get in queue
-            Thread.pass until pool.num_waiting_in_queue == 1
-
-            # create a different, later thread, that will attempt to do a "group action",
-            # but because of the group action semantics it should be able to preempt the
-            # first_thread when a connection is made available
-            second_thread = Thread.new do
-              pool.send(group_action_method)
-              second_thread_done.count_down
+            begin
+              # create a first_thread and let it get into the FIFO queue first
+              first_thread = Thread.new do
+                pool.with_connection { second_thread_done.wait }
+              end
+
+              # wait for first_thread to get in queue
+              Thread.pass until pool.num_waiting_in_queue == 1
+
+              # create a different, later thread, that will attempt to do a "group action",
+              # but because of the group action semantics it should be able to preempt the
+              # first_thread when a connection is made available
+              second_thread = Thread.new do
+                pool.send(group_action_method)
+                second_thread_done.set
+              end
+
+              # wait for second_thread to get in queue
+              Thread.pass until pool.num_waiting_in_queue == 2
+
+              # return the only available connection
+              pool.checkin(conn)
+
+              # if the second_thread is not able to preempt the first_thread,
+              # they will temporarily (until either of them timeouts with ConnectionTimeoutError)
+              # deadlock and a join(2) timeout will be reached
+              assert second_thread.join(2), "#{group_action_method} is not able to preempt other waiting threads"
+
+            ensure
+              # post test clean up
+              failed = !second_thread_done.set?
+
+              if failed
+                second_thread_done.set
+
+                puts
+                puts ">>> test_disconnect_and_clear_reloadable_connections_are_able_to_preempt_other_waiting_threads / #{group_action_method}"
+                p [first_thread, second_thread]
+                p pool.stat
+                p pool.connections.map(&:owner)
+
+                first_thread.join(2)
+                second_thread.join(2)
+
+                puts '---'
+                p [first_thread, second_thread]
+                p pool.stat
+                p pool.connections.map(&:owner)
+                puts '<<<'
+                puts
+              end
+
+              first_thread.join(10) || raise("first_thread got stuck")
+              second_thread.join(10) || raise("second_thread got stuck")
             end
-
-            # wait for second_thread to get in queue
-            Thread.pass until pool.num_waiting_in_queue == 2
-
-            # return the only available connection
-            pool.checkin(conn)
-
-            # if the second_thread is not able to preempt the first_thread,
-            # they will temporarily (until either of them timeouts with ConnectionTimeoutError)
-            # deadlock and a join(2) timeout will be reached
-            failed = true unless second_thread.join(2)
-
-            #--- post test clean up start
-            second_thread_done.count_down if failed
-
-            first_thread.join
-            second_thread.join
-            #--- post test clean up end
-
-            flunk "#{group_action_method} is not able to preempt other waiting threads" if failed
           end
         end
       end
-- 
cgit v1.2.3