File: pooling_spec.rb

package info (click to toggle)
ruby-dataobjects 0.10.17-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 608 kB
  • sloc: ruby: 2,984; makefile: 4
file content (162 lines) | stat: -rw-r--r-- 3,576 bytes parent folder | download | duplicates (2)
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