module DataObjects::Pooling

Notes

Provides pooling support to class it got included in.

Pooling of objects is a faster way of aquiring instances of objects compared to regular allocation and initialization because instances are keeped in memory reused.

Classes that include Pooling module have re-defined new method that returns instances acquired from pool.

Term resource is used for any type of poolable objects and should NOT be thought as DataMapper Resource or ActiveResource resource and such.

In Data Objects connections are pooled so that it is unnecessary to allocate and initialize connection object each time connection is needed, like per request in a web application.

Pool obviously has to be thread safe because state of object is reset when it is released.

Public Class Methods

__new(*args)
Alias for: new
__pool_lock() click to toggle source
# File lib/data_objects/pooling.rb, line 112
def self.__pool_lock
  @__pool_lock
end
__pool_wait() click to toggle source
# File lib/data_objects/pooling.rb, line 116
def self.__pool_wait
  @__pool_wait
end
__pools() click to toggle source
# File lib/data_objects/pooling.rb, line 124
def self.__pools
  @__pools
end
append_pool(pool) click to toggle source
# File lib/data_objects/pooling.rb, line 86
def self.append_pool(pool)
  lock.synchronize do
    pools << pool
  end
  DataObjects::Pooling.scavenger
end
included(target) click to toggle source
# File lib/data_objects/pooling.rb, line 100
def self.included(target)
  lock.synchronize do
    unless target.respond_to? :__pools
      target.class_eval do
        class << self
          alias __new new
        end

        @__pools     = {}
        @__pool_lock = Mutex.new
        @__pool_wait = ConditionVariable.new

        def self.__pool_lock
          @__pool_lock
        end

        def self.__pool_wait
          @__pool_wait
        end

        def self.new(*args)
          (@__pools[args] ||= __pool_lock.synchronize { Pool.new(self.pool_size, self, args) }).new
        end

        def self.__pools
          @__pools
        end

        def self.pool_size
          8
        end
      end
    end
  end
end
lock() click to toggle source
# File lib/data_objects/pooling.rb, line 93
def self.lock
  @lock ||= Mutex.new
end
new(*args) click to toggle source
# File lib/data_objects/pooling.rb, line 120
def self.new(*args)
  (@__pools[args] ||= __pool_lock.synchronize { Pool.new(self.pool_size, self, args) }).new
end
Also aliased as: __new
pool_size() click to toggle source
# File lib/data_objects/pooling.rb, line 128
def self.pool_size
  8
end
pools() click to toggle source
# File lib/data_objects/pooling.rb, line 82
def self.pools
  @pools ||= Set.new
end
scavenger() click to toggle source
# File lib/data_objects/pooling.rb, line 47
def self.scavenger
  unless scavenger?
    @scavenger = Thread.new do
      running = true
      while running do
        # Sleep before we actually start doing anything.
        # Otherwise we might clean up something we just made
        sleep(scavenger_interval)

        lock.synchronize do
          pools.each do |pool|
            # This is a useful check, but non-essential, and right now it breaks lots of stuff.
            # if pool.expired?
            pool.lock.synchronize do
              if pool.expired?
                pool.dispose
              end
            end
            # end
          end

          # The pool is empty, we stop the scavenger
          # It wil be restarted if new resources are added again
          if pools.empty?
            running = false
          end
        end
      end # loop
    end
  end

  @scavenger.priority = -10
  @scavenger
end
scavenger?() click to toggle source
# File lib/data_objects/pooling.rb, line 43
def self.scavenger?
  defined?(@scavenger) && !@scavenger.nil? && @scavenger.alive?
end
scavenger_interval() click to toggle source
# File lib/data_objects/pooling.rb, line 250
def self.scavenger_interval
  60
end

Public Instance Methods

detach() click to toggle source
# File lib/data_objects/pooling.rb, line 140
def detach
  @__pool.delete(self) unless @__pool.nil?
end
release() click to toggle source
# File lib/data_objects/pooling.rb, line 136
def release
  @__pool.release(self) unless @__pool.nil?
end