copiousfreetime / rev forked from tarcieri/rev

Rev is a high performance event library for Ruby built on top of libev

This URL has Read+Write access

Fri Jul 10 20:44:44 -0700 2009
commit  1955be80c164006130302a45661e5325f5d58d4e
tree    182860837cb9db8830262cd6075d83ea52fe1dec
parent  9ea46c2092faac14c87f39e44fe996fe8f7c004d
rev /
name age message
file CHANGES Loading commit data...
file HOW_TO_RUN_FROM_GIT Mon Aug 18 14:53:03 -0700 2008 Update documentation to point to the Git reposi... [tarcieri]
file LICENSE Mon Dec 17 22:57:26 -0800 2007 Initial commit of codebase to trunk git-svn-id... [tarcieri]
file README
file Rakefile
directory examples/ Sun Feb 01 14:11:49 -0800 2009 Some more examples [tarcieri]
directory ext/
directory lib/
file rev.gemspec
directory spec/
README
= Rev

Rev is an event library for Ruby, built on the libev event library which 
provides a cross-platform interface to high performance system calls .  This 
includes the epoll system call for Linux, the kqueue system call for BSDs and 
OS X, and the completion ports interface for Solaris.

Rev also binds asynchronous wrappers to Ruby's core socket classes so you can
use them in conjunction with Rev to build asynchronous event-driven 
applications.

You can include Rev in your programs with:

 require 'rubygems'
 require 'rev'

For more information, consult the RubyForge page:

http://rev.rubyforge.org

http://rubyforge.org/projects/rev

Questions?  Sign up for the mailing list at:

http://rubyforge.org/mailman/listinfo/rev-talk

The latest development code is available via github at:

git://github.com/tarcieri/rev.git

== Anatomy

Rev builds on two core classes which bind to the libev API:

* Rev::Loop - This class represents an event loop which uses underlying high
  performance system calls to wait for events.

* Rev::Watcher - This is the base class for event observers.  Once you attach
  an event observer to a loop and start running it, you will begin receiving
  callbacks to particlar methods when events occur.

== Watchers

There are presently two types of watchers:

* Rev::IOWatcher - This class waits for an IO object to become readable,
  writable, or both.

* Rev::TimerWatcher - This class waits for a specified duration then fires
  an event.  You can also configure it to fire an event at specified intervals.

== Using Watchers

Watchers have five important methods:

* attach(loop) - This binds a watcher to the specified event loop.  If the
  watcher is already bound to a loop it will be detached first, then attached
  to the new one.

* detach - This completely unbinds a watcher from an event loop.

* disable - This stops the watcher from receiving events but does not unbind
  it from the loop.  If you are trying to toggle a watcher on and off, it's
  best to use this method (and enable) as it performs better than completely
  removing the watcher from the event loop.

* enable - This re-enables a watcher which has been disabled in the past.
  The watcher must still be bound to an event loop.

* evloop - This returns the Rev::Loop object which the watcher is currently
  bound to.

== Asynchronous Wrappers

Several classes which provide asynchronous event-driven wrappers for Ruby's
core socket classes are also provided.  Among these are:

* Rev::TCPSocket - A buffered wrapper to core Ruby's Socket class for use with
  TCP sockets.  You can asynchronously create outgoing TCP connections using 
  its Rev::TCPSocket.connect method.  Rev::TCPSocket provides write buffering
  to ensure that writing never blocks, and has asynchronous callbacks for
  several events, including when the connection is opened (or failed), when
  data is received, when the write buffer has been written out completely,
  and when the connection closes.

* Rev::TCPServer - A wrapper for TCPServer which creates new instances of
  Rev::TCPSocket (or any subclass you wish to provide) whenever an incoming
  connection is received.

* Rev::HttpClient - An HTTP/1.1 client with support for chunked encoding
  and streaming response processing through asynchronous callbacks.

== Example Program

Below is an example of how to write an echo server:

  require 'rev'
  HOST = 'localhost'
  PORT = 4321

  class EchoServerConnection < Rev::TCPSocket
    def on_connect
      puts "#{remote_addr}:#{remote_port} connected"
    end

    def on_close
      puts "#{remote_addr}:#{remote_port} disconnected"
    end

    def on_read(data)
      write data
    end
  end

  server = Rev::TCPServer.new(HOST, PORT, EchoServerConnection)
  server.attach(Rev::Loop.default)

  puts "Echo server listening on #{HOST}:#{PORT}"
  Rev::Loop.default.run

Here a new observer type (EchoServerConnection) is made by subclassing an
existing one and adding new implementations to existing event handlers.

A new event loop is created, and a new Rev::TCPServer (whose base class is
Rev::Watcher) is created and attached to the event loop.

Once this is done, the event loop is started with event_loop.run.  This method
will block until there are no active watchers for the loop or the loop is
stopped explicitly with event_loop.stop.

== Defining Callbacks at Runtime

It's often tedious to subclass in order to just change one callback.  Rev 
gives you the ability to change event callbacks on the fly (provided you
haven't overridden them in a subclass).  This is especially useful for small
one off programs or just experimenting with the API.

Any callback (methods prefixed with on_*) can be set on the fly by passing it
a block. (NOTE: Ruby 1.9/1.8.7 only)

Below is an example of using this syntax.  It implements an echo server
identical to the one above:

  HOST = '127.0.0.1'
  PORT = 4321

  server = Rev::TCPServer.new(HOST, PORT) do |c|
    c.on_connect { puts "#{remote_addr}:#{remote_port} connected" }
    c.on_close   { puts "#{remote_addr}:#{remote_port} disconnected" }
    c.on_read    { |data| write data }
  end

  server.attach(Rev::Loop.default)

  puts "Echo server listening on #{HOST}:#{PORT}"
  Rev::Loop.default.run

As you can see, it provides a more concise (albeint slightly slower) 
expression of the same server as above, without the need to subclass.

Rev::TCPServer will automatically yield new connections if a block is
given.  In this case the "c" variable being passed to the block is
a new instance of Rev::TCPSocket representing the newly created connection.

The above example sets the on_connect, on_close, and on_read callbacks each
time a new connection is created.