Tony Arcieri
2/16/2008 12:07:00 AM
[Note: parts of this message were removed to make it a legal post.]
On Fri, Feb 15, 2008 at 3:49 PM, Roger Pack <rogerpack2005@gmail.com> wrote:
> What would you say is the difference between rev and eventmachine?
> Thoughts? (Obviously I can see that both work with 1.9, rev only with
> 1.9).
>
Rev's main design goal was to minimize C and build upon Ruby's existing
socket APIs and OpenSSL bindings. A lot of the features that allow Rev to
be predominantly Ruby showed up in 1.9, namely the *_nonblock versions of
various Socket methods. For this reason, a lot of C code was needed to
implement these features in Ruby 1.8 (which is how EventMachine solved the
problem), but is no longer necessary in Ruby 1.9.
In Rev. there's two kinds of things: event loops (Rev::Loop) and Watchers
(event observers), which are all derived from the abstract base class
Rev::Watcher. Subclasses of Rev::Watcher translate incoming events to
higher and higher levels of abstraction. The code is factored into lots of
small classes that wrap up common behavior in an inheritence hierarchy, for
example Rev::Sockets and Files are subclassed from Rev::IO, and
Rev::TCPSocket and Rev::UNIXSocket are subclassed from Rev::Socket. I'm
sure this is how EventMachine's C++ code is factored internally, but from
the Ruby perspective much of the functionality appears in the flat
EventMachine namespace, which is a Module that exposes singleton methods
like EM.start_tcp_server, EM.start_unix_server, etc instead of using
objects/inheritance.
Being object oriented makes Rev's API a lot more Ruby-like, and having as
much code as possible in Ruby means it's easier for people to hack on it
since they don't have to know C++. The only things that are C in Rev are
the libev bindings (which let you monitor Ruby IO objects for
readability/writability, and provide timers), a class for doing high-speed
buffered network I/O, and a subclass of OpenSSL::SSL::SSLSocket which adds
nonblocking I/O support. Everything else is written in Ruby.
Building on libev means that the codebase for doing portable,
high-performance cross-platform event monitoring has already undergone a lot
of debugging and performance tuning. There's been a lot of problems with
the EventMachine bindings to epoll, and any improvements to that code will
only come from people interested in EventMachine specifically (who know
C/C++). libev is in use by a number of people, most notably Rubinius.
libev was also written by a performance-obsessed C guru and benchmarks quite
nicely, outperforming libevent.
Unfortunately, I haven't done benchmarks of Rev vs. EventMachine. Maybe
I'll do some when there's an official EventMachine release with Ruby
1.9support. If Rev does outperform EventMachine on Ruby
1.9, it might be interesting to do what libev did for libevent: monkeypatch
some core files of the pure Ruby implementation of EventMachine to use Rev
as their underlying implementation. EventMachine packs support for a lot of
features Rev does not, and is used by many, many projects (including some of
my own) whereas Rev hasn't seen much use yet.
My main motivation for writing Rev was a feature sorely lacking from
EventMachine which was crucial to implementing Revactor: stoppable /
restartable event monitors.
Every subclass of Rev::Watcher supports the following methods:
attach(loop) - monitor this watcher using the given event loop
disable - temporarily disable event reception
enable - re-enable event reception
detach - remove this watcher from the event loop (for when you're done with
a watcher, e.g. when the connection closes, although it's automatic in that
case)
Many features of the Actor API in Revactor depend on being able to
temporarily disable event monitoring. Revactor translates events into
messages which get sent to Actor's mailboxes, so it's important those
messages are only sent when an Actor is expecting them. This means *any*
event source wrapped by the Actor API must be stoppable/restartable, and in
Rev, these features are implemented in the Rev::Watcher base class, so
they're available in every subclass.
--
Tony Arcieri
ClickCaster, Inc.
tony@clickcaster.com