Class: FiberPool

Inherits:
Object
  • Object
show all
Defined in:
lib/fiber_pool.rb,
lib/fiber_pool/pool.rb,
lib/fiber_pool/version.rb

Constant Summary collapse

VERSION =
"1.0.0"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(count = 100) ⇒ FiberPool

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



15
16
17
18
19
20
21
# File 'lib/fiber_pool/pool.rb', line 15

def initialize(count = 100)
  @fibers,@busy_fibers,@queue = [],{},[]
  
  count.times do |i|
    add_fiber()
  end
end

Class Method Details

.require_lib(path) ⇒ Object



2
3
4
# File 'lib/fiber_pool.rb', line 2

def self.require_lib(path)
  require File.expand_path("../#{path}", __FILE__)
end

Instance Method Details

#add_fiberObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fiber_pool/pool.rb', line 23

def add_fiber
  fiber = Fiber.new do |block|
    loop do
      block.call
      unless @queue.empty?
        block = @queue.shift
      else
        @busy_fibers.delete(Fiber.current.object_id)
        @fibers.unshift Fiber.current
        block = Fiber.yield
      end
    end
  end
  
  @fibers << fiber
  fiber
end

#spawn(&block) ⇒ Object

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



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/fiber_pool/pool.rb', line 43

def spawn(&block)
  # resurrect dead fibers
  @busy_fibers.values.reject(&:alive?).each do |f|
    @busy_fibers.delete(f.object_id)
    add_fiber()
  end
  
  if fiber = @fibers.shift
    @busy_fibers[fiber.object_id] = fiber
    fiber.resume(block)
  else
    @queue << block
  end
  
  fiber
end