FEATURE: added method for draining idle connections

This commit is contained in:
Sam 2014-08-11 15:13:37 +10:00
parent eeff092ead
commit 9fc7c145b3
2 changed files with 80 additions and 0 deletions

View File

@ -0,0 +1,33 @@
class ActiveRecord::ConnectionAdapters::ConnectionPool
# drain all idle connections
# if idle_time is specified only connections idle for N seconds will be drained
def drain(idle_time=nil)
synchronize do
@available.clear
@connections.delete_if do |conn|
try_drain?(conn, idle_time)
end
@connections.each do |conn|
@available.add conn if !conn.in_use?
end
end
end
private
def try_drain?(conn, idle_time)
if !conn.in_use?
if !idle_time || conn.last_use < idle_time.seconds.ago
conn.disconnect!
return true
end
end
false
end
end

View File

@ -0,0 +1,47 @@
require 'spec_helper'
describe 'pool drainer' do
let(:pool) do
ActiveRecord::Base.connection_pool
end
it 'can correctly drain the connection pool' do
pool.drain
old = pool.connections.length
old.should == 1
Thread.new do
conn = pool.checkout
pool.checkin conn
end.join
pool.connections.length.should == (old+1)
pool.drain
pool.connections.length.should == old
end
it 'can drain with idle time setting' do
pool.drain
old = pool.connections.length
old.should == 1
Thread.new do
conn = pool.checkout
pool.checkin conn
end.join
pool.connections.length.should == (old+1)
pool.drain(1.minute)
pool.connections.length.should == (old+1)
# make sure we don't corrupt internal state
20.times do
conn = pool.checkout
pool.checkin conn
pool.drain
end
end
end