Bindings, Platforms, and Innovation
This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.
Tracking change and innovation in the enterprise software development community
Posted by Mirko Stocker on Jun 25, 2008 02:05 PM
EventMachine is a framework for network and concurrent programming, based on the Reactor design pattern. The Reactor pattern describes a service handler that receives events and dispatches them to registered event handlers. The benefits of the reactor pattern are a clear separation between the event dispatching and the application logic that handles the events, without complicating the code with multithreading.
EventMachine provides a high-level interface to network sockets and tries to hide the lower level operations. EventMachine's goals are:
- Extremely high scalability, performance and stability for the most demanding production environments; and
- An API that eliminates the complexities of high-performance threaded network programming, allowing engineers to concentrate on their application logic.
Let's take a look at a small example; a simple chat server:
require 'eventmachine'
module Chat
# Called after the connection with a client has been established
def post_init
# Add ourselves to the list of clients
(@@connections ||= []) << self
send_data "Please enter your name: "
end
# Called on new incoming data from the client
def receive_data data
# The first message from the user is its name
@name ||= data.strip
@@connections.each do |client|
# Send the message from the client to all other clients
client.send_data "#{@name} says: #{data}"
end
end
end
# Start a server on localhost, using port 8081 and hosting our Chat application
EventMachine::run do
EventMachine::start_server "localhost", 8081, Chat
end
We talked to Francis Cianfrocca, the main developer of EventMachine (EM). We asked him about his motivations to develop EventMachine:
I originally started the project because I wanted to write a high-performance message-oriented middleware that could be programmed easily in scripting languages, including Ruby. At this point, there have been a great many projects written in EM, but the middleware project still hasn't been done! I was looking for a way to create an access-policy enforcement solution that would be extremely scalable, for global enterprises. And I wanted a communications framework that would be extremely fast but also have proper security built into it.
EventMachine is used by Thin (A fast and very simple Ruby web server), Swiftiply (a clustering proxy server for web applications), Evented Mongrel (Mongrel that has its network traffic handled by EventMachine), Sparrow (lightweight queue [..] that speaks memcache) and Juggernaut (plugin for Ruby on Rails [that lets] the server initiate a connection and push data to the client). Francis also wrote his own web framework:
Mine is called Unicycle, and it's intended for RESTful applications that must contact other applications in order to fulfill Web requests. That also is based on EM, using EM's built-in HTTP server.
Version 0.12 of EventMachine has recently been released:
There are some performance enhancements and minor features on 0.12, but the primary motivation was to release a binary gem for Windows that had all the features we've added since 0.8.
The core of the EventMachine, the Reactor, has originally been implemented in C++ and has bindings for other languages besides Ruby. There's also a pure Ruby implementation, and one of the next versions will see the release of a Java implementation to be used with JRuby:
The most important new feature to be released soon will be full support for JRuby. This required a complete re-implementation of the reactor core in Java, which actually went quite well. Charles Nutter and his team have done a tremendous job on JRuby, and I think it has a lot of potential. I'm also very intrigued by Rubinius. The interesting thing about Rubinius is its support for fibers, which enables a more natural programming style for EM. I've already experimented with it in Ruby 1.9, but I'm hesitant to fork the API until more people are using the newer platforms. One of the key design goals for EM always has been maximum compatibility.
We asked Francis to elaborate on the advantages of EventMachine:
The key technical reason to use EM is because it enables a programming model that avoids threads. Threaded programming is of course a very well-known model, especially for network servers, but it has some very deep problems. There is a relatively small class of problems which are a good match for the threaded model. Network servers happen to be one of them, because it's usually possible to construct a non-overlapping working set for each request. But of course it's very difficult to get a threaded program 100% correct if it has any shared state between threads, or if it relies on operations to be properly sequenced across threads. And in Ruby, there's the additional problem that threading is very expensive.
The other reason to use EM is that we support a wide range of network protocols out of the box. The goal is to provide programmers with a large set of mature, high-performance tools that are easy to drop into their applications. This is what makes EM different from the many projects that are simply trying to implement the reactor model.
We also spoke of event driven programming, and why it is easier to work with, compared to a threaded model:
A lot has been written about the fact that event-driven programs are not theoretically any faster than threaded ones, and that is true. But in practice, I think the event-driven model is easier to work with, if you want to get to extremely high scalability and performance while still ensuring maximum robustness. I write programs that have to run for months or years without crashing, leaking memory, or exhibiting any kind of lumpy performance, so in practice, event-driven programming works better. Now, here's the problem with event-driven programming: you have to write "backwards." A threaded model stores your program state (inefficiently) in local variables on a runtime stack. In EM you have to do that yourself, which is very unintuitive to programmers who are used to threads. This is why I'm interested in fibers, because it opens the possibility of writing what looks to the programmer like blocking I/O, but still is evented and uses no threads.
Let's take a closer look at this, using an HTTP server as an example:
Think of an HTTP server. With threads, you simply read the socket and block until all the data has been retrieved from the remote peer. With events, you get the data as soon as it appears, with no waiting and no scheduling overhead—But it may not be complete! Your program has to detect that it hasn't yet received enough data to interpret the request, and it needs to store the partial data. But the next event that your program handles will possibly contain data for a different connection, so you have to keep all of this straight. The threading abstraction is a very heavyweight way of keeping those working sets separate, so it makes the programming task arguably more intuitive. But the evented model is not really so hard to learn. Nevertheless, I think this is the biggest barrier to wider use of event-driven programming.
Luckily, this is where EventMachine comes into play:
Now one of the things that EM does is to wrap up the standard protocols so that all of this is largely hidden from the programmer. Unlike low-level libraries like libev, which provide only a reactor core, EM seeks to provide robust implementations for all the standard network protocols, for example, email. EM includes a well-written handler for both the client and server side of SMTP. So an EM programmer only has to write code to handle events associated with complete email messages. There's no need to touch the underlying protocol. But still you have all the other benefits of the evented model (high speed, high scalability).
You can find more about EventMachine on the official Rubyforge website and on rubyeventmachine.com:
We recently opened up the community site rubyeventmachine.com which is a Trac implementation done by Jason Roelofs. And there is also an EventMachine IRC channel. Plenty of people, including Kirk Haines, James Tucker (raggi) and Aman Gupta (tmm1) have contributed a lot to EM. Also the people who do thin, Marc-André Cournoyer, have contributed a lot of ideas.
Ensuring Code Quality in Multi-threaded Applications
Usage Landscape: Enterprise Open Source Data Integration
Download the Free Adobe® Flex® Builder 3 Trial
Give-away eBook – Confessions of an IT Manager
Effective Management of Static Analysis Vulnerabilities and Defects
This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.
This article explores the use of JBoss and jBPM to implement design solutions that effectively address the issue of orchestrating long running activities.
This presentation covers the use of graph databases as an optimal solution for data that is difficult to fit in static tables, rapidly evolving data or data that has a lot of optional attributes.
This session introduces Real Options and shows how it can help in running your project. Real Options is a decision-making process that can be used to manage risk.
This article discusses the use of bindings on services and references (including the instance of non-configured bindings) as the means to implement SCA communications in a Web and SOA environment.
After a short introduction to DSLs, Scott Davis plays with the keyboard showing how to approach the creation of a DSL by typing working snippets of Groovy code that get executed.
IBM Rational and InfoQ present, Scaling Agile with C/ALM, an eBook showing organizations how to become “finely tuned software delivery machines” by enabling team integration and scaling.
Amanda Laucher presents a real life enterprise application written in F#. She shows actual code snippets, explaining design decisions and suggesting how to use some of the F# constructs.
No comments
Watch Thread Reply