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