
EventMachine: scalable non-blocking i/o in ruby - tmm1
http://timetobleed.com/eventmachine-scalable-non-blocking-io-in-ruby/
======
davidw
This is what's frustrating about being a Tcl fan: Tcl had this something like
15 years ago, because it was necessary for Tk. "Tcl don't get no respect" :-/

That said, though, what separates the "men from the Erlangs" is that in Tcl,
Ruby, Python, Javascript, and company, "never block the reactor" is the name
of the game, you can't do a while { 1 } { something } in your event handler or
it will wedge the whole thing.

In Erlang, thanks to its built in scheduler, you can.

~~~
axod
Why is that a good thing?

Essentially what you're saying is that Erlang allows you to make idiotic
mistakes?

~~~
jerf
No. Things that are _not_ Erlang turn you into a human compiler, forced to
manually chop your code into pieces for the pleasure of the computer. Erlang
allows you to actually write things without doing the chopping up the
scheduler should do.

Event-based libraries are great hacks on top of weak languages/runtimes that
allow those weak languages to hobble forward into the present, but they
shouldn't be confused for the right approach in the future. I do hope they
don't become trendy.

Of course, look for them to become trendy, then for one or more of them to
rediscover the pleasure of actually writing code in a straightforward manner,
so they will provide you with a preprocessor that tries to do the chopping up
for you, but still won't solve the problem of doing too much work in one
timeslice. Then they'll rediscover that cooperative multitasking was abandoned
years ago for good reason.

You know, there's nothing new under the sun, but sometimes you just wonder...
this much hype around _cooperative multitasking_? Seriously?

~~~
axod
I can't disagree with you enough.

I don't want anything else to decide what order my code runs. I want it to run
in the order I decide.

Once you move away from the stupid "I want these 100 things to run at the same
time", and realize that's impossible unless you have 100 CPUs, then you can
start to move forwards and learn a better way.

Event based / async programming is simple once you get used to it, it's hugely
liberating, and _extremely_ efficient. It reduces code complexity, and means
you _know_ what order your code will execute in. Something that I kinda like
knowing.

~~~
tptacek
You don't really know a priori the order everything is executing in, unless
you control the remote ends of all the connections and you have no timers.
I've lost days of my life to timer cancellation bugs.

~~~
axod
Sure, you don't know the _exact_ order your code executes if it has external
inputs :) but you know that your code will execute 'linearly' and then adhere
to any program flow constructs you put in, and nothing else.

You can be 100% sure that it won't suddenly stop executing here, and jump over
to some totally disconnected bit of code for a while, then jump back.

You don't have to worry about a whole class of bugs which take up weeks/months
of peoples time.

Not sure what you mean @ timers, I was really talking about async/event driven
in general. Timers seem like an implementation specific detail on top of that.
I haven't really seen any issues myself there :/

~~~
jerf
"You don't have to worry about a whole class of bugs which take up
weeks/months of peoples time."

I reiterate, you need to spend some quality time with Erlang. This time I
recommend <http://erlang.org/download/erlang-book-part1.pdf> ; Erlang has some
powerful answers to those "whole class of bugs".

(Actually, not being aware of that does rather make sense of the rest of your
views. I have first-hand experience that Erlang really does make those
problems go away; I like to say that Erlang takes concurrent programming from
an exponential problem to a polynomial one. It still isn't "trivial" and I
don't know that it ever can be, but it makes it so a _human_ can do it.)

------
tptacek
As luck would have it, I'm sitting here writing a fuzzer for a trading
protocol in EventMachine as we speak.

Ruby and async network programming go together like gin and vermouth. It's one
of the reasons I'm so happy with Ruby's block/lambda support, and so irritated
with Python's: many of the basic programming idioms for evented network code
have direct support in the Ruby language.

I've done a fair bit of Twisted Python programming in the past, and I find
EventMachine to be far more intuitive and flexible. On the other hand,
EventMachine will crash on me once in a blue moon, and it swallows exceptions,
which is extremely frustrating. They're both great packages.

The big problem that still needs solving for EventMachine is evented adapters
for an ORM (any ORM). You've always been able to talk to MySQL over an evented
socket, but that's clumsy compared to DataMapper.

I am still totally not sold that Ruby threads are tenable, so a lot of the
"advanced" stuff in EventMachine does nothing for me. It's great even without
it.

~~~
jrockway
_I am still totally not sold that Ruby threads are tenable, so a lot of the
"advanced" stuff in EventMachine does nothing for me._

FWIW, threads based on an event backend are a solved problem in Perl. The Coro
library is what EM is trying to be; they should really take a look. ("Oh but
it's PERL!!!!" Yeah, and it actually works.)

~~~
tptacek
Maybe, but part of the value of async programming is never having to thread,
so none of this really lights me up.

~~~
BrianHammond
Honest question: is there a purely event-driven I/O framework (no threads
anywhere)?

The one that a lot of people have gotten excited about recently is Node.js and
that uses threads for file I/O (libeio).

~~~
tptacek
EventMachine doesn't thread unless you ask it to. I use EventMachine in Ruby
and libevent in C with nary a mutex in sight.

~~~
BrianHammond
I see. My (wrong) understanding was that EM used a thread pool to do file I/O
like Node.js. It appears to add the file descriptor to the event loop's watch
list.

------
donw
I recently had a chance to play around with EventMachine, as I wanted to set
up an event-based scheduler within my application.

I was not impressed.

If you try and mix 'EventMachine' and 'other threadsafe code', it seems to
fall down pretty hard. In my case, it would run anything executed via
next_tick, but would refuse to run any timers... unless I defined a periodic
timer in the main event loop, after which timers started working... but only
every time the periodic timer executed.

I dug through the code to see if I could fix the problem, and gave up after
trying to figure out why they seem to implement timers in two different ways,
and it doesn't seem very threadsafe (next_tick is, but none of the timer code
looks to be).

EM also expects that your entire application will run inside the EventMachine
loop; there's no way to ask EM for a Reactor that you can then hand events.

If you're not running threaded code, then EM will probably work just fine; the
Thin webserver looks to be a really nice Rack deployment option if you're on
MRI.

If you need to mix EM up with anything else running on the same VM, look
elsewhere.

------
aantix
Take a look at Juggernaut. It's an event server based on EventMachine that
provides nice integration with Rails. Streams events to the client via Flash.

------
filterfish
Excellent preso. If you are interested in eventmachine or just getting into it
read this.

------
macournoyer_
Great presentation! Some exciting new stuff in Eventmachine.

