Class: Extlib::Pooling::Pool

Inherits:
Object
  • Object
show all
Defined in:
lib/gems/extlib-0.9.8/lib/extlib/pooling.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_size, resource, args) ⇒ Pool

Returns a new instance of Pool.

Raises:

  • (ArgumentError)


128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 128

def initialize(max_size, resource, args)
  raise ArgumentError.new("+max_size+ should be a Fixnum but was #{max_size.inspect}") unless Fixnum === max_size
  raise ArgumentError.new("+resource+ should be a Class but was #{resource.inspect}") unless Class === resource

  @max_size = max_size
  @resource = resource
  @args = args

  @available = []
  @used      = {}
  Extlib::Pooling::append_pool(self)
end

Instance Attribute Details

#availableObject (readonly)

Returns the value of attribute available.



125
126
127
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 125

def available
  @available
end

#usedObject (readonly)

Returns the value of attribute used.



126
127
128
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 126

def used
  @used
end

Instance Method Details

#delete(instance) ⇒ Object



195
196
197
198
199
200
201
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 195

def delete(instance)
  lock.synchronize do
    instance.instance_variable_set(:@__pool, nil)
    @used.delete(instance.object_id)
  end
  nil
end

#disposeObject



216
217
218
219
220
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 216

def dispose
  flush!
  @resource.__pools.delete(@args)
  !Extlib::Pooling::pools.delete?(self).nil?
end

#expired?Boolean

Returns:

  • (Boolean)


222
223
224
225
226
227
228
229
230
231
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 222

def expired?
  @available.each do |instance|
    if Extlib.exiting || instance.instance_variable_get(:@__allocated_in_pool) + Extlib::Pooling.scavenger_interval <= Time.now
      instance.dispose
      @available.delete(instance)
    end
  end

  size == 0
end

#flush!Object



212
213
214
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 212

def flush!
  @available.pop.dispose until @available.empty?
end

#inspectObject



208
209
210
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 208

def inspect
  "#<Extlib::Pooling::Pool<#{@resource.name}> available=#{@available.size} used=#{@used.size} size=#{@max_size}>"
end

#lockObject



141
142
143
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 141

def lock
  @resource.__pool_lock
end

#newObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 153

def new
  instance = nil
  begin
    lock.synchronize do
      if @available.size > 0
        instance = @available.pop
        @used[instance.object_id] = instance
      elsif @used.size < @max_size
        instance = @resource.__new(*@args)
        raise InvalidResourceError.new("#{@resource} constructor created a nil object") if instance.nil?
        raise InvalidResourceError.new("#{instance} is already part of the pool") if @used.include? instance
        instance.instance_variable_set(:@__pool, self)
        instance.instance_variable_set(:@__allocated_in_pool, Time.now)
        @used[instance.object_id] = instance
      else
        # Let's see whether we have multiple threads
        # If we do, there is a chance we might be released
        # at some point in the future and thus we wait.
        # If there are no other threads, we exhaust the pool
        # here and there is no more hope... So we throw an
        # exception.
        if ThreadGroup::Default.list.size <= 2
          raise ThreadStopError.new(size)
        else
          wait.wait(lock)
        end
      end
    end
  end until instance
  instance
end

#release(instance) ⇒ Object



185
186
187
188
189
190
191
192
193
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 185

def release(instance)
  instance.instance_variable_set(:@__allocated_in_pool, Time.now)
  lock.synchronize do
    @used.delete(instance.object_id)
    @available.push(instance)
    wait.signal
  end
  nil
end

#scavenge_intervalObject



149
150
151
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 149

def scavenge_interval
  @resource.scavenge_interval
end

#sizeObject Also known as: length



203
204
205
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 203

def size
  @used.size + @available.size
end

#waitObject



145
146
147
# File 'lib/gems/extlib-0.9.8/lib/extlib/pooling.rb', line 145

def wait
  @resource.__pool_wait
end