class Fibre::FiberPool
Attributes
pool_queue_size[R]
pool_size[R]
queue[R]
reserved[R]
Public Class Methods
new(pool_size: DEFAULT_POOL_SIZE, pool_queue_size: DEFAULT_POOL_QUEUE_SIZE)
click to toggle source
Initialize fiber's pool
# File lib/fibre/fiber_pool.rb, line 22 def initialize(pool_size: DEFAULT_POOL_SIZE, pool_queue_size: DEFAULT_POOL_QUEUE_SIZE) @pool_size = pool_size @pool_queue_size = pool_queue_size @reserved = {} @queue = [] @pool = @pool_size.times.collect { ::Fiber.new(&self.method(:fiber_entry)) } end
Public Instance Methods
checkout(&b)
click to toggle source
Borrow fiber from the pool and call the block inside
# File lib/fibre/fiber_pool.rb, line 31 def checkout(&b) spec = { block: b, parent: ::Fiber.current } if @pool.empty? raise "The fiber queue has been overflowed" if @queue.size > @pool_queue_size @queue.push spec return end @pool.shift.tap do |fiber| @reserved[fiber.object_id] = spec fiber.resume(spec) end self end
Private Instance Methods
checkin(result=nil)
click to toggle source
Return the fiber into the pool
# File lib/fibre/fiber_pool.rb, line 83 def checkin(result=nil) @reserved.delete ::Fiber.current.object_id @pool.unshift ::Fiber.current ::Fiber.yield end
fiber_entry(spec)
click to toggle source
There is entrypoint running fibers
# File lib/fibre/fiber_pool.rb, line 51 def fiber_entry(spec) loop do raise "wrong spec in fiber block" unless spec.is_a?(Hash) begin before!(spec) spec[:block].call# *Fiber.current.args after!(spec) # catch ArgumentError, IOError, EOFError, IndexError, LocalJumpError, NameError, NoMethodError # RangeError, FloatDomainError, RegexpError, RuntimeError, SecurityError, SystemCallError # SystemStackError, ThreadError, TypeError, ZeroDivisionError rescue StandardError => e if error.empty? raise Fibre::FiberError.new(e) else error!(e) end # catch NoMemoryError, ScriptError, SignalException, SystemExit, fatal etc #rescue Exception end unless @queue.empty? spec = @queue.shift next end spec = checkin end end