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