module EventMachine::Synchrony
Public Class Methods
Fiber-aware EventMachine
timer: wraps the passed in block within a new fiber (new fiber on every invocation) to allow you to continue using synchrony methods
# File lib/em-synchrony.rb, line 106 def self.add_periodic_timer(interval, &blk) EM.add_periodic_timer(interval) do Fiber.new { blk.call }.resume end end
Fiber-aware EventMachine
timer: wraps the passed in block within a new fiber context such that you can continue using synchrony methods
# File lib/em-synchrony.rb, line 96 def self.add_timer(interval, &blk) EM::Timer.new(interval) do Fiber.new { blk.call }.resume end end
Fiber-aware EM.defer
# File lib/em-synchrony.rb, line 120 def self.defer op = nil, &blk fiber = Fiber.current EM.defer(op || blk, lambda{ |result| fiber.resume(result) }) Fiber.yield end
Routes to EM::Synchrony::Keyboard
# File lib/em-synchrony.rb, line 145 def self.gets EventMachine::Synchrony::Keyboard.new.gets end
Interrupt current fiber to give chance to other fibers
# File lib/em-synchrony.rb, line 151 def self.interrupt fiber = Fiber.current EM.next_tick { fiber.resume } Fiber.yield end
Fiber-aware EM.next_tick convenience function
# File lib/em-synchrony.rb, line 114 def self.next_tick(&blk) EM.next_tick { Fiber.new { blk.call }.resume } end
Overrides behavior of kernel.sleep Allows to add custom behavior, e.g. logging or redirection to EM::Synchrony.sleep . Calling 'sleep' in this function calls the actual kernel method.
# File lib/em-synchrony.rb, line 139 def self.on_sleep(&blk) Kernel.em_synchrony_sleep_hook = blk end
Fiber-aware sleep function using an EM
timer
Execution is stopped for specified amount of seconds and then automatically resumed (just like regular sleep) except without locking the reactor thread
# File lib/em-synchrony.rb, line 86 def self.sleep(secs) fiber = Fiber.current EM::Timer.new(secs) { fiber.resume } Fiber.yield end
sync is a close relative to inlineCallbacks from Twisted (Python)
Synchrony.sync
allows you to write sequential code while using asynchronous or callback-based methods under the hood. Example:
result = EM::Synchrony.sync EventMachine::HttpRequest.new(URL).get p result.response
As long as the asynchronous function returns a Deferrable object, which has a “callback” and an “errback”, the sync methond will automatically yield and automatically resume your code (via Fibers) when the call either succeeds or fails. You do not need to patch or modify the Deferrable object, simply pass it to EM::Synchrony.sync
# File lib/em-synchrony.rb, line 63 def self.sync(df) f = Fiber.current xback = proc do |*args| if f == Fiber.current return args.size == 1 ? args.first : args else f.resume(*args) end end df.callback(&xback) df.errback(&xback) Fiber.yield end
Fiber-aware EM.system
# File lib/em-synchrony.rb, line 128 def self.system cmd, *args fiber = Fiber.current EM.system(cmd, *args){ |out, status| fiber.resume( [out, status] ) } Fiber.yield end