class Sequel::FiberPool

Constants

DEFAULT_SIZE

Attributes

allocated[R]
available[R]
max_size[R]

Public Class Methods

new(db, opts = {}) click to toggle source
Calls superclass method
# File lib/sequel/fiber_pool.rb, line 8
def initialize(db, opts = {})
  super
  @available = []
  @allocated = {}
  @pending = []

  @max_size = opts[:max_connections] || DEFAULT_SIZE
  hold {}
end

Public Instance Methods

disconnect(server = nil) click to toggle source
# File lib/sequel/fiber_pool.rb, line 46
def disconnect(server = nil)
  @available.each{ |conn| db.disconnect_connection(conn) }
  @available.clear
end
hold(server = nil) { |conn| ... } click to toggle source
# File lib/sequel/fiber_pool.rb, line 22
def hold(server = nil)
  fiber = Fiber.current
  fiber_id = fiber.object_id

  if conn = @allocated[fiber_id]
    skip_release = true
  else
    conn = acquire(fiber) until conn
  end

  begin
    yield conn

  rescue ::Sequel::DatabaseDisconnectError => e
    db.disconnect_connection(conn)
    drop_failed(fiber_id)
    skip_release = true

    raise
  ensure
    release(fiber_id) unless skip_release
  end
end
size() click to toggle source
# File lib/sequel/fiber_pool.rb, line 18
def size
  @available.length + @allocated.length
end

Private Instance Methods

acquire(fiber) click to toggle source
# File lib/sequel/fiber_pool.rb, line 53
def acquire(fiber)
  if conn = @available.pop
    @allocated[fiber.object_id] = conn
  else
    if size < max_size
      allocate_new_connection(fiber.object_id)
    else
      @pending << fiber
      Fiber.yield
    end
  end
end
allocate_new_connection(fiber_id) click to toggle source
# File lib/sequel/fiber_pool.rb, line 66
def allocate_new_connection(fiber_id)
  @allocated[fiber_id] = true
  @allocated[fiber_id] = make_new(DEFAULT_SERVER)
rescue Exception => e
  drop_failed(fiber_id)
  raise e
end
drop_failed(fiber_id) click to toggle source

drop failed connection (or a mark) from the pool and ensure that the pending requests won't starve

# File lib/sequel/fiber_pool.rb, line 76
def drop_failed(fiber_id)
  @allocated.delete(fiber_id)
  if pending = @pending.shift
    EM.next_tick { pending.resume }
  end
end
release(fiber_id) click to toggle source
# File lib/sequel/fiber_pool.rb, line 83
def release(fiber_id)
  conn = @allocated.delete(fiber_id)
  if pending = @pending.shift
    @allocated[pending.object_id] = conn
    EM.next_tick { pending.resume conn}
  else
    @available << conn
  end
end