class EventCore::FiberSource

Source for Ruby Fibers run on the mainloop. When a fiber yields it returns control to the mainloop. It supports async sub-tasks in sync-style programming by yielding Procs. See MainLoop.add_fiber for details.

Public Class Methods

new(loop, proc=nil) click to toggle source
Calls superclass method EventCore::Source::new
# File lib/event_core.rb, line 203
def initialize(loop, proc=nil)
  super()
  raise "First arg must be a MainLoop: #{loop}" unless loop.is_a? MainLoop
  raise "Second arg must be a Proc: #{proc.class}" unless (proc.is_a? Proc or proc.nil?)

  @loop = loop

  create_fiber(proc) if proc
end

Public Instance Methods

close!() click to toggle source
Calls superclass method EventCore::Source#close!
# File lib/event_core.rb, line 224
def close!
  super
  @fiber = nil
end
consume_event_data!() click to toggle source
Calls superclass method EventCore::Source#consume_event_data!
# File lib/event_core.rb, line 218
def consume_event_data!
  event_data = super
  @ready = true
  event_data
end
create_fiber(proc) click to toggle source
# File lib/event_core.rb, line 229
def create_fiber(proc)
  raise "Arg must be a Proc: #{proc.class}" unless proc.is_a? Proc
  raise "Fiber already created for this source" if @fiber

  @fiber = Fiber.new { proc.call }

  @ready = true

  trigger { |async_task_data|
    task = @fiber.resume(async_task_data)

    # If yielding, maybe spawn an async sub-task?
    if @fiber.alive?
      if task.is_a? Proc
        raise "Fibers on the main loop must take exactly 1 argument. Proc takes #{task.arity}" unless task.arity == 1
        @ready = false # don't fire again until task is done
        @loop.add_once {
          fiber_task = FiberTask.new(self)
          task.call(fiber_task)
        }
      elsif task.nil?
        # all good, just yielding until next loop iteration
      else
        raise "Fibers that yield must return nil or a Proc: #{task.class}"
      end
    end

    next @fiber.alive?
  }

  nil
end
ready!(event_data=nil) click to toggle source
Calls superclass method EventCore::Source#ready!
# File lib/event_core.rb, line 213
def ready!(event_data=nil)
  super(event_data)
  @loop.send_wakeup
end