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