Sha256: 8f312d548872b8d3ba25d80da715c38c3b8aab2228a0457fca2d164dba2304e5

Contents?: true

Size: 1.57 KB

Versions: 1

Compression:

Stored size: 1.57 KB

Contents

require 'connection_pool/timed_queue'

# Generic connection pool class for e.g. sharing a limited number of network connections
# among many threads.  Note: Connections are eager created.
#
# Example usage with block (faster):
#
#    @pool = ConnectionPool.new { Redis.new }
#
#    @pool.with do |redis|
#      redis.lpop if redis.llen('my-list') > 0
#    end
#
# Example usage replacing a global connection (slower):
#
#    REDIS = ConnectionPool.new { Redis.new }
#
#    def do_work
#      REDIS.lpop if REDIS.llen('my-list') > 0
#    end
#
# Accepts the following options:
# - :size - number of connections to pool, defaults to 5
# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
#
class ConnectionPool
  DEFAULTS = { :size => 5, :timeout => 5 }

  def initialize(options={})
    raise ArgumentError, 'Connection pool requires a block' unless block_given?

    @available = TimedQueue.new
    @options = DEFAULTS.merge(options)
    @options[:size].times do
      @available << yield
    end
    @busy = []
  end

  def with(&block)
    yield checkout
  ensure
    checkin
  end

  def method_missing(name, *args)
    checkout.send(name, *args)
  ensure
    checkin
  end

  private

  def checkout
    Thread.current[:"current-#{self.object_id}"] ||= begin
      conn = @available.timed_pop(@options[:timeout])
      @busy << conn
      conn
    end
  end

  def checkin
    conn = Thread.current[:"current-#{self.object_id}"]
    Thread.current[:"current-#{self.object_id}"] = nil
    @busy.delete(conn)
    @available << conn
    nil
  end

end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
connection_pool-0.0.1 lib/connection_pool.rb