1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
require 'timeout'
describe "DataObjects::Pooling" do
before do
Object.send(:remove_const, :Person) if defined?(Person)
class ::Person
include DataObjects::Pooling
attr_accessor :name
def initialize(name)
@name = name
end
def dispose
@name = nil
end
end
Object.send(:remove_const, :Overwriter) if defined?(Overwriter)
class ::Overwriter
def self.new(*args)
instance = allocate
instance.send(:initialize, *args)
instance.overwritten = true
instance
end
include DataObjects::Pooling
attr_accessor :name
def initialize(name)
@name = name
@overwritten = false
end
def overwritten?
@overwritten
end
def overwritten=(value)
@overwritten = value
end
class << self
remove_method :pool_size if instance_methods(false).any? { |m| m.to_sym == :pool_size }
def pool_size
pool_size = if RUBY_PLATFORM =~ /java/
20
else
2
end
pool_size
end
end
def dispose
@name = nil
end
end
end
after :each do
DataObjects::Pooling.lock.synchronize do
DataObjects::Pooling.pools.each do |pool|
pool.lock.synchronize do
pool.dispose
end
end
end
end
it "should maintain a size of 1" do
bob = Person.new('Bob')
fred = Person.new('Fred')
ted = Person.new('Ted')
Person.__pools.each do |args, pool|
expect(pool.size).to eq(1)
end
bob.release
fred.release
ted.release
Person.__pools.each do |args, pool|
expect(pool.size).to eq(1)
end
end
it "should track the initialized pools" do
bob = Person.new('Bob') # Ensure the pool is "primed"
expect(bob.name).to eq('Bob')
expect(bob.instance_variable_get(:@__pool)).not_to be_nil
expect(Person.__pools.size).to eq(1)
bob.release
expect(Person.__pools.size).to eq(1)
expect(DataObjects::Pooling::pools).not_to be_empty
sleep(1.2)
# NOTE: This assertion is commented out, as our MockConnection objects are
# currently in the pool.
# DataObjects::Pooling::pools.should be_empty
expect(bob.name).to be_nil
end
it "should allow you to overwrite Class#new" do
bob = Overwriter.new('Bob')
expect(bob).to be_overwritten
bob.release
end
it "should allow multiple threads to access the pool" do
t1 = Thread.new do
bob = Person.new('Bob')
sleep(1)
bob.release
end
expect do
bob = Person.new('Bob')
t1.join
bob.release
end.not_to raise_error
end
it "should allow you to flush a pool" do
bob = Overwriter.new('Bob')
Overwriter.new('Bob').release
bob.release
expect(bob.name).to eq('Bob')
expect(Overwriter.__pools[['Bob']].size).to eq(2)
Overwriter.__pools[['Bob']].flush!
expect(Overwriter.__pools[['Bob']].size).to eq(0)
expect(bob.name).to be_nil
end
it "should wake up the scavenger thread when exiting" do
bob = Person.new('Bob')
bob.release
DataObjects.exiting = true
sleep(1)
expect(DataObjects::Pooling.scavenger?).to be_falsey
end
it "should be able to detach an instance from the pool" do
bob = Person.new('Bob')
expect(Person.__pools[['Bob']].size).to eq(1)
bob.detach
expect(Person.__pools[['Bob']].size).to eq(0)
end
end
|