Cool.io (formerly known as Rev, and pronounced like Coolio of Gangster’s
Paradise fame) is an event framework for Ruby built on libev, the same
library that provides high performance asynchronous I/O for Node.js. Cool.io
is great for building TCP clients and servers which handle large numbers
of
connections and are primarily I/O bound. Cool.io also provides APIs for
filesystem monitoring. Cool.io is an alternative to EventMachine, albeit
one
which using Ruby’s own native I/O primitives rather than reinventing
them,
and does as much as possible in Ruby instead of C, which should make it
easier for interested contributors to hack on.
Cool.io supports the following Ruby implementations:
Ruby 1.8.6+
Ruby 1.9.0+
Rubinius HEAD
Cool.io includes backwards compatibility for Rev, so applications built
using Rev can depend on the cool.io gem but still “require ‘rev’” and
use
the Rev toplevel constant instead of Cool.io’s cool new Cool.io
“constant”.
Backwards compatibility with Rev will be removed in a future release.
Support for building asynchronous HTTP servers with Cool.io is provided
through the Rainbows! asynchronous HTTP web server (based on Unicorn): http://rainbows.rubyforge.org/
Cool beans… I’ve been wanting to try out Cool.io (well, Rev
actually) ever since I started using Twisted and EventMachine. Also, I
like your trickery for the Cool.io constant.
Quick question… any chance Cool.io works in JRuby?
Also, I like your trickery for the Cool.io constant.
Thanks… although actually using Cool.io instead of Coolio adds an
extra
method call so if you care about speed you probably shouldn’t use it (at
least in the event loop itself)
Quick question… any chance Cool.io works in JRuby?
Unfortunately no which is a bit sad because I do a lot of stuff with
JRuby. I’ve thought about writing a JRuby backend for it.
Yes, it’ll probably happen next week, there are a few other Rainbows!
things I’ve been slacking on.
Sweet. I wanted to present Rev/Revactor on Rainbows! at RubyConf but
couldn’t find any examples to get me started (beyond use :Rev and use
:Revactor)
It’d be great if your Rainbows! documentation had a trivial example of
building an async HTTP request handler using Cool.io or Revactor.
Heh, I don’t actually have much a clue what interests people when it
comes to async apps, I barely use the web myself.
I would imagine it’s like writing any regular application with
Rev/Revactor, you could make async HTTP requests to other backends and
maybe some databases with adapters for them…
They’re both pretty good for serving things with only local
dependencies (apps running off TokyoCabinet/SQLite/GDBM, etc)
and can maintain many idle client connections with keepalive.
(crank keepalive_timeout up from the default 5s).
Heh, I don’t actually have much a clue what interests people when it
comes to async apps, I barely use the web myself.
Yet you’ve written over 9000 HTTP servers… lol
I would imagine it’s like writing any regular application with
Rev/Revactor, you could make async HTTP requests to other backends and
maybe some databases with adapters for them…
Well, as a particularly useful example… how would you write an HTTP
proxy
that used Rainbows! as the server and Rev as the client? Rev has an
asynchronous HTTP client… how would you handle an incoming HTTP
request in
Unicorn, make an async HTTP request with Rev’s client, then stream the
response back to the client? Or vice versa for an upload server (e.g.
imagine an HTTP server that uploads files to S3)
How would you write something like that with Rainbows‽
As a more interesting example, Revactor implements a synchronous HTTP
client
which is backed by fibers. How could you write a Rainbows! async HTTP
server
that streamed the responses to a listening actor in the form of
inter-Actor
messages?
I had an idea for an app I wanted to write as a demo for my RubyConf
talk
but I never dug into Rainbows! and figured out how. It was to be called
the
“Warholizer”. I wanted to have an HTTP client connected to the Twitter
streaming API, monitoring for the hashtag #warholize. When a new result
occurs, the Warholizer will perform a google image search for the text
included in the Tweet, or rather 4 searches in parallel… for the given
search term in 4 preselected colors. Once complete it can HTTP push the
result to a long polling HTTP client, which sits there in the browser
and
dumps the results for new tweets into the page.
It uses several parts of the MRI C API which I can only assume are
unimplemented by JRuby.
I gave it a shot, and it got as far as compiling loop.c:
loop.c: In function ‘Coolio_Loop_run_nonblock’:
loop.c:277: error: ‘TRAP_BEG’ undeclared (first use in this function)
loop.c:277: error: (Each undeclared identifier is reported only once
loop.c:277: error: for each function it appears in.)
loop.c:279: error: ‘TRAP_END’ undeclared (first use in this function)
make: *** [loop.o] Error 1
I don’t know what TRAP_BEG and TRAP_END do in MRI, but those would be
the next ones to implement in JRuby’s cext support…
TRAP_BEG and TRAP_END are for MRI 1.8. This is a fallback for if Cool.io
doesn’t find the rb_thread_blocking_region() function, which allows it
to
make blocking system calls in a multithreaded environment. You’ll
probably
want to implement rb_thread_blocking_region() instead. I believe 1.9
additionally implements TRAP_BEG and TRAP_END using some C macro magic
which
generates an rb_thread_blocking_region() call.
Beyond that, it’s going to need GetOpenFile() and the FPTR_TO_FD()
macro.
On Wed, Dec 8, 2010 at 9:56 PM, Charles Oliver N.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.