Skip to content

Commit

Permalink
fix ruby 1.9 deadlock problem, fixes #5736 add connection pool tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Hemant Kumar authored and tenderlove committed Oct 6, 2010
1 parent a0552d6 commit 2a04110
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
Expand Up @@ -75,10 +75,7 @@ def initialize(spec)
@queue = @connection_mutex.new_cond

# default 5 second timeout unless on ruby 1.9

This comment has been minimized.

Copy link
@Empact

Empact Oct 7, 2010

Contributor

Note this comment is now defunct

This comment has been minimized.

Copy link
@gnufied

gnufied Oct 7, 2010

Contributor

My bad, I think tenderlove will have to take care of it.

@timeout =
if RUBY_VERSION < '1.9'
spec.config[:wait_timeout] || 5
end
@timeout = spec.config[:wait_timeout] || 5

# default max pool size to 5
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
Expand Down Expand Up @@ -161,7 +158,6 @@ def clear_stale_cached_connections!
keys = @reserved_connections.keys - Thread.list.find_all { |t|
t.alive?
}.map { |thread| thread.object_id }

keys.each do |key|
checkin @reserved_connections[key]
@reserved_connections.delete(key)
Expand Down Expand Up @@ -194,16 +190,18 @@ def checkout
checkout_new_connection
end
return conn if conn
# No connections available; wait for one
if @queue.wait(@timeout)

@queue.wait(@timeout)

if(@checked_out.size < @connections.size)
next
else
# try looting dead threads
clear_stale_cached_connections!
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."
end
end

end
end
end
Expand Down
29 changes: 29 additions & 0 deletions activerecord/test/cases/connection_pool_test.rb
Expand Up @@ -26,6 +26,35 @@ def checkin conn
"threads should have been removed")
assert_equal pool.checkins.length, threads.length
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

0 comments on commit 2a04110

Please sign in to comment.