From: Tony Arcieri Date: 2008-02-16T09:06:53+09:00 Subject: Re: eventmachine and rev ------=_Part_2865_28505790.1203120418854 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline On Fri, Feb 15, 2008 at 3:49 PM, Roger Pack 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 ------=_Part_2865_28505790.1203120418854--