fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
This commit is contained in:
parent
a0552d653b
commit
2a04110f26
|
@ -75,10 +75,7 @@ module ActiveRecord
|
||||||
@queue = @connection_mutex.new_cond
|
@queue = @connection_mutex.new_cond
|
||||||
|
|
||||||
# default 5 second timeout unless on ruby 1.9
|
# default 5 second timeout unless on ruby 1.9
|
||||||
@timeout =
|
@timeout = spec.config[:wait_timeout] || 5
|
||||||
if RUBY_VERSION < '1.9'
|
|
||||||
spec.config[:wait_timeout] || 5
|
|
||||||
end
|
|
||||||
|
|
||||||
# default max pool size to 5
|
# default max pool size to 5
|
||||||
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
|
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
|
||||||
|
@ -161,7 +158,6 @@ module ActiveRecord
|
||||||
keys = @reserved_connections.keys - Thread.list.find_all { |t|
|
keys = @reserved_connections.keys - Thread.list.find_all { |t|
|
||||||
t.alive?
|
t.alive?
|
||||||
}.map { |thread| thread.object_id }
|
}.map { |thread| thread.object_id }
|
||||||
|
|
||||||
keys.each do |key|
|
keys.each do |key|
|
||||||
checkin @reserved_connections[key]
|
checkin @reserved_connections[key]
|
||||||
@reserved_connections.delete(key)
|
@reserved_connections.delete(key)
|
||||||
|
@ -194,16 +190,18 @@ module ActiveRecord
|
||||||
checkout_new_connection
|
checkout_new_connection
|
||||||
end
|
end
|
||||||
return conn if conn
|
return conn if conn
|
||||||
# No connections available; wait for one
|
|
||||||
if @queue.wait(@timeout)
|
@queue.wait(@timeout)
|
||||||
|
|
||||||
|
if(@checked_out.size < @connections.size)
|
||||||
next
|
next
|
||||||
else
|
else
|
||||||
# try looting dead threads
|
|
||||||
clear_stale_cached_connections!
|
clear_stale_cached_connections!
|
||||||
if @size == @checked_out.size
|
if @size == @checked_out.size
|
||||||
raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
|
raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,6 +26,35 @@ module ActiveRecord
|
||||||
"threads should have been removed")
|
"threads should have been removed")
|
||||||
assert_equal pool.checkins.length, threads.length
|
assert_equal pool.checkins.length, threads.length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_checkout_behaviour
|
||||||
|
pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
|
||||||
|
connection = pool.connection
|
||||||
|
assert_not_nil connection
|
||||||
|
threads = []
|
||||||
|
4.times do |i|
|
||||||
|
threads << Thread.new(i) do |pool_count|
|
||||||
|
connection = pool.connection
|
||||||
|
assert_not_nil connection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
threads.each {|t| t.join}
|
||||||
|
|
||||||
|
Thread.new do
|
||||||
|
threads.each do |t|
|
||||||
|
thread_ids = pool.instance_variable_get(:@reserved_connections).keys
|
||||||
|
assert thread_ids.include?(t.object_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
pool.connection
|
||||||
|
threads.each do |t|
|
||||||
|
thread_ids = pool.instance_variable_get(:@reserved_connections).keys
|
||||||
|
assert !thread_ids.include?(t.object_id)
|
||||||
|
end
|
||||||
|
end.join()
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue