README.md

You don't have to choose between threaded and evented IO! Celluloid::IO
provides an event-driven IO system for building fast, scalable network
applications that integrates directly with the
Celluloid actor library, making it
easy to combine both threaded and evented concepts. Celluloid::IO is ideal for
servers which handle large numbers of mostly-idle connections, such as Websocket
servers or chat/messaging systems.

Celluloid::IO provides a different class of actor: one that's slightly slower
and heavier than standard Celluloid actors, but one which contains a
high-performance reactor just like EventMachine or Cool.io. This means
Celluloid::IO actors have the power of both Celluloid actors and evented
I/O loops. Unlike certain other evented I/O systems which limit you to a
single event loop per process, Celluloid::IO lets you make as many actors as
you want, system resources permitting.

Rather than callbacks, Celluloid::IO exposes a synchronous API built on duck
types of Ruby's own IO classes, such as TCPServer and TCPSocket. These classes
work identically to their core Ruby counterparts, but in the scope of
Celluloid::IO actors provide "evented" performance. Since they're drop-in
replacements for the standard classes, there's no need to rewrite every
library just to take advantage of Celluloid::IO's event loop and you can
freely switch between evented and blocking IO even over the lifetime of a
single connection.

Celluloid::IO uses the nio4r gem
to monitor IO objects, which provides cross-platform and cross-Ruby
implementation access to high-performance system calls such as epoll
and kqueue.

The very first thing including Celluloid::IO does is also include the
Celluloid module, which promotes objects of this class to concurrent Celluloid
actors each running in their own thread. Before trying to use Celluloid::IO
you may want to familiarize yourself with Celluloid in general.
Celluloid actors can each be thought of as being event loops. Celluloid::IO actors
are heavier but have capabilities similar to other event loop-driven frameworks.

While this looks like a normal Ruby TCP server, there aren't any threads, so
you might expect this server can only handle one connection at a time.
However, this is all you need to do to build servers that handle as many
connections as you want, and it happens all within a single thread.

The magic in this server which allows it to handle multiple connections
comes in three forms:

Replacement classes: Celluloid::IO includes replacements for the core
TCPServer and TCPSocket classes which automatically use an evented mode
inside of Celluloid::IO actors. They're named Celluloid::IO::TCPServer and
Celluloid::IO::TCPSocket, so they're automatically available inside
your class when you include Celluloid::IO.

Asynchronous method calls: You may have noticed that while the methods
of EchoServer are named run and handle_connection, they're invoked as
run! and handle_connection!. This queues these methods to be executed
after the current method is complete. You can queue up as many methods as
you want, allowing asynchronous operation similar to the "call later" or
"next tick" feature of Twisted, EventMachine, and Node. This echo server
first kicks off a background task for accepting connections on the server
socket, then kicks off a background task for each connection.

Reactor + Fibers: Celluloid::IO is a combination of Actor and Reactor
concepts. The blocking mechanism used by the mailboxes of Celluloid::IO
actors is an nio4r-powered reactor.
When the current task needs to make a blocking I/O call, it first makes
a non-blocking attempt, and if the socket isn't ready the current task
is suspended until the reactor detects the operation is ready and resumes
the suspended task.

The result is an API for doing evented I/O that looks identical to doing
synchronous I/O. Adapting existing synchronous libraries to using evented I/O
is as simple as having them use one of Celluloid::IO's provided replacement
classes instead of the core Ruby TCPSocket and TCPServer classes.

Status

The rudiments of TCPServer and TCPSocket are in place and ready to use. It is now
fully nonblocking, including DNS resolution, which effectively makes Celluloid::IO
feature complete as a nonblocking I/O system.

Basic UDPSocket support is in place. On JRuby, recvfrom makes a blocking call
as the underlying recvfrom_nonblock call is not supported by JRuby.

No UNIXSocket support yet, sorry (patches welcome!)

Contributing to Celluloid::IO

Fork this repository on github

Make your changes and send me a pull request

If I like them I'll merge them

If I've accepted a patch, feel free to ask for a commit bit!

License

Copyright (c) 2012 Tony Arcieri. Distributed under the MIT License. See
LICENSE.txt for further details.

Contains code originally from the RubySpec project also under the MIT License
Copyright (c) 2008 Engine Yard, Inc. All rights reserved.