Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
175 lines (139 sloc) 4.47 KB
require "spec/helper/all"
DELAY = 0.25
QUERY = "select sleep(#{DELAY})"
describe EventMachine::Synchrony::ConnectionPool do
it "should queue requests if pool size is exceeded" do
EventMachine.run do
db = EventMachine::Synchrony::ConnectionPool.new(size: 1) do
Mysql2::EM::Client.new
end
Fiber.new {
start = now
multi = EventMachine::Synchrony::Multi.new
multi.add :a, db.aquery(QUERY)
multi.add :b, db.aquery(QUERY)
res = multi.perform
(now - start.to_f).should be_within(DELAY * 2 * 0.15).of(DELAY * 2)
res.responses[:callback].size.should == 2
res.responses[:errback].size.should == 0
EventMachine.stop
}.resume
end
end
it "should execute multiple async pool requests within same fiber" do
EventMachine.run do
db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
Mysql2::EM::Client.new
end
Fiber.new {
start = now
multi = EventMachine::Synchrony::Multi.new
multi.add :a, db.aquery(QUERY)
multi.add :b, db.aquery(QUERY)
res = multi.perform
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
res.responses[:callback].size.should == 2
res.responses[:errback].size.should == 0
EventMachine.stop
}.resume
end
end
it "should share connection pool between different fibers" do
EventMachine.run do
db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
Mysql2::EM::Client.new
end
Fiber.new {
start = now
results = []
fiber = Fiber.current
2.times do |n|
Fiber.new {
results.push db.query(QUERY)
fiber.transfer if results.size == 2
}.resume
end
# wait for workers
Fiber.yield
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
results.size.should == 2
EventMachine.stop
}.resume
end
end
it "should share connection pool between different fibers & async requests" do
EventMachine.run do
db = EventMachine::Synchrony::ConnectionPool.new(size: 5) do
Mysql2::EM::Client.new
end
Fiber.new {
start = now
results = []
fiber = Fiber.current
2.times do |n|
Fiber.new {
multi = EventMachine::Synchrony::Multi.new
multi.add :a, db.aquery(QUERY)
multi.add :b, db.aquery(QUERY)
results.push multi.perform
fiber.transfer if results.size == 3
}.resume
end
Fiber.new {
# execute a synchronous requests
results.push db.query(QUERY)
fiber.transfer if results.size == 3
}.resume
# wait for workers
Fiber.yield
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
results.size.should == 3
EventMachine.stop
}.resume
end
end
describe '#pool_status' do
it 'should return right initial size' do
(1..10).each do |count|
pool = EventMachine::Synchrony::ConnectionPool.new(size: count) { }
status = pool.pool_status
expect(status).to include available: count
expect(status).to include reserved: 0
expect(status).to include pending: 0
end
end
it 'should return up-to-date statusrmation' do
sleep = 0.5
count = 5
EM.run do
pool = EM::Synchrony::ConnectionPool.new(size: count) do
-> { EM::Synchrony.sleep(sleep) }
end
(1..count).each do |used|
Fiber.new { pool.call }.resume
status = pool.pool_status
expect(status).to include available: count - used
expect(status).to include reserved: used
expect(status).to include pending: 0
end
(1..count).each do |used|
Fiber.new { pool.call }.resume
status = pool.pool_status
expect(status).to include available: 0
expect(status).to include reserved: count
expect(status).to include pending: used
end
Fiber.new {
EM::Synchrony.sleep(sleep + 0.1)
expect(pool.pool_status).to include pending: 0
EM::Synchrony.sleep(sleep + 0.1)
status = pool.pool_status
expect(status).to include available: count
expect(status).to include reserved: 0
expect(status).to include pending: 0
EM.stop
}.resume
end
end
end
end