Tuesday, August 16, 2011

Syncronous coding style with EventMachine and Fibers

I did this a while ago. I am not really happy with it. As I've said before. Event driven code doesn't bother me. Here is an example.

require 'fiber'
require 'eventmachine'

class AsyncIO < EM::Connection
  include EM::P::LineText2
  def initialize df
    @df = df
  end
  def receive_line line
    @df.succeed line
  end
end

def get_line
  f = Fiber.current
  df = EM::DefaultDeferrable.new
  df.callback { |line| f.resume(line) }
  EM.connect '127.0.0.1', 3000, AsyncIO, df
  return Fiber.yield
end

EM.run {
  Fiber.new {
    line = get_line
    puts line
    EM.stop
  }.resume
}

The truth is you should look at EM::Sychrony. Ilya Grigorik explains in he own Blog, how Fibers can help you write synchronous code while keeping the goodness of AsyncIO (ala EventMachine).

I don't find event driven code to be "callback hell" like Ilya Grigorik does. I find evented code easier to read than synchronous code sometimes. In Synchronous code you have to check every time if it failed and why. That is

if (rc < 0)
with
switch (errno) case EINTR:
code after every network call. In event driven code that stuff is dealt with in the event-loop and you just have to define the error callback once.

Ah well just use Node.js . If JavaScript event driven programming is "to hard" for your delicate sensibilities then explain to me how Millions of Web-monkeys pull it off everyday in the browser.