class ConnectionQueue

A thread-safe implementation of a connection queue. Supports adding, removing, and polling a connection synchronously, and doesn't create more than `max_size` elements. All connections are created lazily (only when needed).

Attributes

max_size[R]
queue[R]

Public Class Methods

new(max_size = 0, &block) click to toggle source
# File lib/redis_pool/connection_queue.rb, line 14
def initialize(max_size = 0, &block)
  @create_block = block
  @created = 0
  @queue = []
  @max_size = max_size
  @lock = Monitor.new
  @lock_cond = @lock.new_cond
end

Public Instance Methods

<<(element)
Alias for: add
add(element) click to toggle source

Adds (or returns) a connection to the available queue, synchronously.

# File lib/redis_pool/connection_queue.rb, line 26
def add(element)
  synchronize do
    @queue.push element
    @lock_cond.signal
  end
end
Also aliased as: <<, push
available_to_create() click to toggle source

Returns the number of available connections to create.

# File lib/redis_pool/connection_queue.rb, line 82
def available_to_create
  @max_size - @created
end
delete(element) click to toggle source

Removes an idle connection from the queue synchronously.

# File lib/redis_pool/connection_queue.rb, line 63
def delete(element)
  synchronize do
    @queue.delete element
  end
end
poll(timeout = 5) click to toggle source

Fetches any available connection from the queue. If a connection is not available, waits for timeout until a connection is available or raises a TimeoutError.

# File lib/redis_pool/connection_queue.rb, line 40
def poll(timeout = 5)
  t0 = Concurrent.monotonic_time
  elapsed = 0
  synchronize do
    loop do
      return get_connection if connection_available?

      connection = create_connection
      return connection if connection

      elapsed = Concurrent.monotonic_time - t0
      raise TimeoutError, 'could not obtain connection' if elapsed >= timeout

      @lock_cond.wait(timeout - elapsed)
    end
  end
end
Also aliased as: pop
pop(timeout = 5)
Alias for: poll
push(element)
Alias for: add
total_available() click to toggle source

Returns the total available connections to be used. This takes into account the number of connections that can be created as well. So it is all connections that can be used AND created.

# File lib/redis_pool/connection_queue.rb, line 75
def total_available
  @max_size - @created + @queue.length
end

Private Instance Methods

connection_available?() click to toggle source
# File lib/redis_pool/connection_queue.rb, line 92
def connection_available?
  !@queue.empty?
end
create_connection() click to toggle source
# File lib/redis_pool/connection_queue.rb, line 102
def create_connection
  return unless @created < @max_size

  conn = @create_block.call
  # TODO: add more stats.
  stats = {
    id: @created,
    alive_since: Time.now.utc,
    last_used_at: Time.now.utc
  }
  @created += 1
  [conn, stats]
end
get_connection() click to toggle source
# File lib/redis_pool/connection_queue.rb, line 96
def get_connection
  conn = @queue.pop
  conn.last[:last_used_at] = Time.now.utc
  conn
end
synchronize(&block) click to toggle source
# File lib/redis_pool/connection_queue.rb, line 88
def synchronize(&block)
  @lock.synchronize(&block)
end