1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #31696 from BrentWheeldon/bmw-connection-pool-load-deadlock

Prevent deadlocks when waiting for connection from pool.
This commit is contained in:
Matthew Draper 2018-08-24 01:42:22 +09:30 committed by GitHub
commit 1f05cc58d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View file

@ -188,7 +188,9 @@ module ActiveRecord
t0 = Time.now
elapsed = 0
loop do
@cond.wait(timeout - elapsed)
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
@cond.wait(timeout - elapsed)
end
return remove if any?

View file

@ -111,6 +111,44 @@ module ActiveRecord
assert_equal connection, t.join.value
end
def test_full_pool_blocking_shares_load_interlock
@pool.instance_variable_set(:@size, 1)
load_interlock_latch = Concurrent::CountDownLatch.new
connection_latch = Concurrent::CountDownLatch.new
able_to_get_connection = false
able_to_load = false
thread_with_load_interlock = Thread.new do
ActiveSupport::Dependencies.interlock.running do
load_interlock_latch.count_down
connection_latch.wait
@pool.with_connection do
able_to_get_connection = true
end
end
end
thread_with_last_connection = Thread.new do
@pool.with_connection do
connection_latch.count_down
load_interlock_latch.wait
ActiveSupport::Dependencies.interlock.loading do
able_to_load = true
end
end
end
thread_with_load_interlock.join
thread_with_last_connection.join
assert able_to_get_connection
assert able_to_load
end
def test_removing_releases_latch
cs = @pool.size.times.map { @pool.checkout }
t = Thread.new { @pool.checkout }