class FiberPool

Attributes

busy_fibers[R]
fibers[R]

gives access to the currently free fibers

generic_callbacks[RW]

Code can register a proc with this FiberPool to be called every time a Fiber is finished. Good for releasing resources like ActiveRecord database connections.

Public Class Methods

new(count = 100) click to toggle source

Prepare a list of fibers that are able to run different blocks of code every time. Once a fiber is done with its block, it attempts to fetch another one from the queue

# File lib/vendor/fiber_pool.rb, line 43
def initialize(count = 100)
  @fibers,@busy_fibers,@queue,@generic_callbacks = [],{},[],[]
  count.times do |i|
    fiber = Fiber.new do |block|
      loop do
        block.call

        # callbacks are called in a reverse order, much like c++ destructor
        Fiber.current[:callbacks].pop.call while Fiber.current[:callbacks].length > 0
        generic_callbacks.each do |cb|
          cb.call
        end

        if @queue.any?
          block = @queue.shift
        else
          @busy_fibers.delete(Fiber.current.object_id)
          @fibers.unshift Fiber.current
          block = Fiber.yield
        end

      end
    end
    fiber[:callbacks] = []
    fiber[:em_keys] = []
    @fibers << fiber
  end
end

Public Instance Methods

spawn(&block) click to toggle source

If there is an available fiber use it, otherwise, leave it to linger in a queue

# File lib/vendor/fiber_pool.rb, line 74
def spawn(&block)
  if fiber = @fibers.shift
    fiber[:callbacks] = []
    @busy_fibers[fiber.object_id] = fiber
    fiber.resume(block)
  else
    @queue << block
  end
  self # we are keen on hiding our queue
end