mirror of
https://github.com/mperham/connection_pool
synced 2023-03-27 23:22:21 -04:00
More testing, threading fixes
This commit is contained in:
parent
27362471c6
commit
5ddef034cf
4 changed files with 36 additions and 28 deletions
|
@ -19,10 +19,8 @@ Create a pool of objects to share amongst the fibers or threads in your Ruby app
|
|||
|
||||
Then use the pool in your application:
|
||||
|
||||
@memcached.with do |dalli|
|
||||
dalli.fetch('some-count', :expires_in => 1.day) do
|
||||
SomeModel.query.count
|
||||
end
|
||||
@memcached.with_connection do |dalli|
|
||||
dalli.get('some-count')
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ class ConnectionPool
|
|||
ensure
|
||||
checkin
|
||||
end
|
||||
alias_method :with_connection, :with
|
||||
|
||||
def method_missing(name, *args)
|
||||
checkout.send(name, *args)
|
||||
|
|
|
@ -4,7 +4,6 @@ require 'timeout'
|
|||
class TimedQueue
|
||||
def initialize
|
||||
@que = []
|
||||
@waiting = []
|
||||
@mutex = Mutex.new
|
||||
@resource = ConditionVariable.new
|
||||
end
|
||||
|
@ -15,22 +14,15 @@ class TimedQueue
|
|||
@resource.signal
|
||||
end
|
||||
end
|
||||
alias << push
|
||||
alias_method :<<, :push
|
||||
|
||||
def timed_pop(timeout=0.5)
|
||||
while true
|
||||
@mutex.synchronize do
|
||||
@waiting.delete(Thread.current)
|
||||
if @que.empty?
|
||||
@waiting.push Thread.current
|
||||
@resource.wait(@mutex, timeout)
|
||||
raise Timeout::Error if @que.empty?
|
||||
else
|
||||
retval = @que.shift
|
||||
@resource.signal
|
||||
return retval
|
||||
end
|
||||
@mutex.synchronize do
|
||||
if @que.empty?
|
||||
@resource.wait(@mutex, timeout)
|
||||
raise Timeout::Error if @que.empty?
|
||||
end
|
||||
return @que.shift
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,38 +3,46 @@ require 'helper'
|
|||
class TestConnectionPool < MiniTest::Unit::TestCase
|
||||
|
||||
class NetworkConnection
|
||||
def initialize
|
||||
@x = 0
|
||||
end
|
||||
def do_something
|
||||
sleep 0.1
|
||||
'foo'
|
||||
@x += 1
|
||||
sleep 0.05
|
||||
@x
|
||||
end
|
||||
def fast
|
||||
@x += 1
|
||||
end
|
||||
end
|
||||
|
||||
def test_basic_multithreaded_usage
|
||||
pool = ConnectionPool.new(:size => 5) { NetworkConnection.new }
|
||||
threads = []
|
||||
10.times do
|
||||
15.times do
|
||||
threads << Thread.new do
|
||||
pool.with do |net|
|
||||
pool.with_connection do |net|
|
||||
net.do_something
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
a = Time.now
|
||||
threads.each(&:join)
|
||||
result = threads.map(&:value)
|
||||
b = Time.now
|
||||
assert((b - a) > 0.2)
|
||||
assert_operator((b - a), :>, 0.125)
|
||||
assert_equal(result, [1,2,3].cycle(5).sort)
|
||||
end
|
||||
|
||||
def test_timeout
|
||||
pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
|
||||
pool = ConnectionPool.new(:timeout => 0.05, :size => 1) { NetworkConnection.new }
|
||||
Thread.new do
|
||||
pool.with do |net|
|
||||
net.do_something
|
||||
sleep 0.2
|
||||
sleep 0.1
|
||||
end
|
||||
end
|
||||
sleep 0.1
|
||||
sleep 0.05
|
||||
assert_raises Timeout::Error do
|
||||
pool.do_something
|
||||
end
|
||||
|
@ -42,6 +50,15 @@ class TestConnectionPool < MiniTest::Unit::TestCase
|
|||
|
||||
def test_passthru
|
||||
pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
|
||||
assert_equal 'foo', pool.do_something
|
||||
assert_equal 1, pool.do_something
|
||||
assert_equal 2, pool.do_something
|
||||
end
|
||||
|
||||
def test_return_value
|
||||
pool = ConnectionPool.new(:timeout => 0.1, :size => 1) { NetworkConnection.new }
|
||||
result = pool.with_connection do |net|
|
||||
net.fast
|
||||
end
|
||||
assert_equal 1, result
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue