Module: EventMachine::Synchrony

Defined in:
lib/em-synchrony.rb,
lib/em-synchrony/amqp.rb,
lib/em-synchrony/thread.rb,
lib/em-synchrony/em-multi.rb,
lib/em-synchrony/iterator.rb,
lib/em-synchrony/keyboard.rb,
lib/em-synchrony/mechanize.rb,
lib/em-synchrony/tcpsocket.rb,
lib/em-synchrony/fiber_iterator.rb,
lib/em-synchrony/connection_pool.rb

Defined Under Namespace

Modules: AMQP, Thread Classes: ConnectionPool, FiberIterator, Iterator, Keyboard, KeyboardHandler, Mechanize, Multi, TCPSocket

Class Method Summary collapse

Class Method Details

.add_periodic_timer(interval, &blk) ⇒ Object

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


106
107
108
109
110
# 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

.add_timer(interval, &blk) ⇒ Object

Fiber-aware EventMachine timer: wraps the passed in block within a new fiber context such that you can continue using synchrony methods


96
97
98
99
100
# 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

.defer(op = nil, &blk) ⇒ Object

Fiber-aware EM.defer


120
121
122
123
124
# 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

.getsObject

Routes to EM::Synchrony::Keyboard


145
146
147
# File 'lib/em-synchrony.rb', line 145

def self.gets
  EventMachine::Synchrony::Keyboard.new.gets
end

.interruptObject

Interrupt current fiber to give chance to other fibers


151
152
153
154
155
# File 'lib/em-synchrony.rb', line 151

def self.interrupt
  fiber = Fiber.current
  EM.next_tick { fiber.resume }
  Fiber.yield
end

.next_tick(&blk) ⇒ Object

Fiber-aware EM.next_tick convenience function


114
115
116
# File 'lib/em-synchrony.rb', line 114

def self.next_tick(&blk)
  EM.next_tick { Fiber.new { blk.call }.resume }
end

.on_sleep(&blk) ⇒ Object

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.


139
140
141
# File 'lib/em-synchrony.rb', line 139

def self.on_sleep(&blk)
  Kernel.em_synchrony_sleep_hook = blk
end

.sleep(secs) ⇒ Object

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


86
87
88
89
90
# File 'lib/em-synchrony.rb', line 86

def self.sleep(secs)
  fiber = Fiber.current
  EM::Timer.new(secs) { fiber.resume }
  Fiber.yield
end

.sync(df) ⇒ Object

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


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 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

.system(cmd, *args) ⇒ Object

Fiber-aware EM.system


128
129
130
131
132
# 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