Skip to content

Instantly share code, notes, and snippets.

@marekjelen
Created March 31, 2012 11:17
Show Gist options
  • Save marekjelen/2262341 to your computer and use it in GitHub Desktop.
Save marekjelen/2262341 to your computer and use it in GitHub Desktop.

Project

Student implements a framework for building asynchronous (event-driven) network applications that will be compatible with all major Ruby implementations - JRuby, MRI, Rubinius. The framework will support multiple networking adapters and provide compatibility layer for EventMachine based applications.

Problem

There are many ways to implement asynchronous applications using low-level libraries - nio4r, java nio, netty, libuv and others. The challenge is to choose the right one and be able to switch it based on a deployment model.

Solution

Framework with consistent API will be implemented that will allow swapping underlaying low-level libraries for it's operations. The framework will be compatible with all major Ruby implementations. With this in mind, the developer does not have to choose what library the application will be written for and will have the possibility to move to different deployment model in the future.

Checklist

  • support for all ruby implementations - JRuby, MRI, Rubinius
  • nested protocol handlers like Netty (?)
  • compatibility layer for legacy EventMachine based application
  • swappable adapters
    • java nio/nio2
    • netty/mina
    • nio4r
    • eventmachine (?)
    • binding to libuv
    • binding to libev/libevent and libaio
    • binding to Boos.Asio
    • binding to QT Async IO
  • all bindings should be be developed using ffi to support all Ruby implementations
  • support for networking adapters
  • support for SSL/TLS for all adapters
  • support for filesystem adapters
  • support for timers (multiple adapters?)
  • support for running time consuming operations on background (multiple adapters?)

Result

As a developer I choose drivers my application uses and add 2+ gems to my project - the library itself and required adapters. I will develop my application with a consistent API. When I need, I may change the adapter gems and the application will run the same. Moving among Ruby implementation may require changing drivers, but will not require changes in the application itself.

@dimonge
Copy link

dimonge commented Mar 31, 2012

Interesting concept!!

@tarcieri
Copy link

tarcieri commented Apr 5, 2012

Cool concept indeed (cool.io/nio4r author here ;)

One thing I'd suggest, if possible, is leveraging nio4r as the Java NIO(2) binding and contributing back to it if there are things missing, rather than supporting both nio4r and your own NIO bindings. nio4r is intended to be a cross-Ruby wrapper for the sort of APIs that Java NIO presents.

The same could be said for libev/uv as well. nio4r binds to the selector-like parts of libev, and will soon support direct buffering on Java NIO, and could potentially take advantage of the direct buffering work that's already been done in libuv.

Having a high-level event framework that's an abstraction over other frameworks is definitely a cool idea though. My question specifically regarding Netty would be that Netty exposes a worker pool model, which is awesome for building multicore apps using evented I/O, but somewhat different from the model offered by other frameworks like Mina/EventMachine/Cool.io.

I'd also like to spin off the timers in Celluloid as a separate gem. They're pure Ruby and designed for use with selectors that take timeouts, so they might provide a good least common denominator solution.

(Also, honestly, I've "retired" Cool.io. I would actually suggest skipping cool.io, but nio4r was made for exactly this sort of project)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment