[ANN] cool.io 0.9.0: a cool event framework for Ruby (formerly knownas Rev) based on libev

T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

Github: https://github.com/tarcieri/cool.io
<https://github.com/tarcieri/cool.io>Rubygems:
https://rubygems.org/gems/cool.io

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/

Changes (from Rev 0.3.2):
- Rename the project to cool.io
- Bump the version all the way to 0.9! Hell yeah! 1.0 soon!
- Rename the toplevel module from Rev to Coolio (with a cool Cool.io style)
- Backwards compatibility with Rev with deprecation warnings
- Use Jeweler to manage the gem
- Update to RSpec 2.0
- Update to libev 4.01
- Initial Rubinius support
 
S

Sean O'Halpin

Great news! I was concerned you'd moved on from Rev - very glad to see
this excellent library getting a new boost of life.

Thanks,
Sean
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

What was the reasoning for this? I actually liked the Rev name :)

Cool.io is ever so slightly less ungooglable
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

Cool.io is ever so slightly less ungooglable

By the way Eric, while Cool.io has backwards compat for Rev, it'd be nice if
you could update Rainbows! to have "use :Coolio" :)
 
B

Bryan Richardson

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?
 
E

Eric Wong

Tony Arcieri said:
Heh.

By the way Eric, while Cool.io has backwards compat for Rev, it'd be nice if
you could update Rainbows! to have "use :Coolio" :)

Yes, it'll probably happen next week, there are a few other Rainbows!
things I've been slacking on.
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

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.
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

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.
 
E

Eric Wong

Tony Arcieri said:
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).
 
T

Tony Arcieri

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 i=
n
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=E2=80=BD

As a more interesting example, Revactor implements a synchronous HTTP clien=
t
which is backed by fibers. How could you write a Rainbows! async HTTP serve=
r
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.

How would I get started on an app like that?

--=20
Tony Arcieri
Medioh! A Kudelski Brand
 
C

Charles Oliver Nutter

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.

What's required to do so? What prevents it from working?

- Charlie
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

What's required to do so? What prevents it from working?


It uses several parts of the MRI C API which I can only assume are
unimplemented by JRuby.
 
C

Charles Oliver Nutter

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 =E2=80=98Coolio_Loop_run_nonblock=E2=80=99:
loop.c:277: error: =E2=80=98TRAP_BEG=E2=80=99 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: =E2=80=98TRAP_END=E2=80=99 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...

https://github.com/jruby/jruby/tree/master/cext/src

- Charlie
 
T

Tony Arcieri

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 whic=
h
generates an rb_thread_blocking_region() call.

Beyond that, it's going to need GetOpenFile() and the FPTR_TO_FD() macro.

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 =91Coolio_Loop_run_nonblock=92:
loop.c:277: error: =91TRAP_BEG=92 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: =91TRAP_END=92 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...

https://github.com/jruby/jruby/tree/master/cext/src

- Charlie


--=20
Tony Arcieri
Medioh! Kudelski
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top