What have you found for these years?

2010-10-29

nack -- Node powered Rack server

nack -- Node powered Rack server

I do think this is pretty smart! Why node.js? Not because it is event-driven,
nor do it is for JavaScript, but because it is based on V8, which is really
*fast*, fast enough to have some revolution. JavaScript which runs on
V8 beats Ruby runs on YARV easily in terms of performance.

So how to take the advantage of V8 and the elegance of Ruby?
Definitely no one would know if this would win in the end,
but using node.js as the HTTP server for Rack application is
not hard at all. Now we can easily compare Ruby server and
node.js with real world applications without hard work!

*

It's fairly easy to understand how this works. Let's go back
to the era of Mongrel... So why Mongrel? Because CGI is simply
not the way to serve web application. So now we have FastCGI,
which is a lot more reasonable for a web application, but failed
at implementation. Then now we have SCGI, which is roughly
in between CGI and FastCGI. If I remember correctly, Passenger
uses SCGI as the internal protocol between web servers and
application servers.

But is it worth the effort to have another protocol just for internal
communication? Mongrel proved that HTTP was good enough even
for internal communication, and that helped a lot because now there's
no much difference between web servers and application servers,
which helps the separation of web servers and application servers.

For instance, now you can simply deploy Mongrel without a reverse
proxy
if the traffic is really low, and later put on Nginx without
changing a line of application code. In short, it's a lot more modular
than the way FastCGI or mod_php is.

And all of these are because the Mongrel HTTP parser is awesome,
awesome enough to sacrifice things used to be, that is, performance.
A more tied system is theoretical more efficient, but harder to maintain,
and the harder it could be maintained, the slower it could be improved.

So suddenly, people running Ruby servers all came to Mongrel.

But later Zed Shaw stopped maintaining, or more importantly,
improving Mongrel, this was really bad for Ruby. Fortunately,
it's an open source software. People started using Mongrel's
HTTP parser to write yet yet yet another web server, mainly
Thin and Unicorn in Ruby's world. I've seen many other servers
are not for Ruby but used Mongrel's HTTP parser as well.

*

Rack, which is another important invention in Ruby's world. It
complements this modular architecture, that is further separate
web framework and web (application) server, make them agnostic
to each other, so that we're not only able to change web servers,
(reverse proxy), but also application servers.

This openness makes the competitions between application servers
and web frameworks easily and fairly. There's no monopolization,
and good competitions make better products.

It's interesting that Rack was inspired by Python's WSGI, but WSGI
seemed not so widely used as Ruby's Rack, and later there were tons
of other similar protocols and libraries invented and were inspired by
Rack but not WSGI. To name a few, Haskell's Hack, JavaScript's
JSGI & Jack, Erlang's EWGI, and Perl's PSGI and Plack. Looks like
WSGI was populated by Rack.

*

So what's all this about nack -- a Node powered Rack server -- anyway?
Essentially, all Rack should know is a Ruby hash called "env",
which plays the role of carrying all the HTTP information and others.
The architecture is something like this:

web server (reverse proxy) <- HTTP -> application server
<- Rack env hash -> web application

nack is simply doing this:

node.js <- somehow -> nack server
<-
JSON that conforms Rack env hash (nack to rack) OR
JSON that encoded from Rack response (rack to nack)
-> web application

So that previously application server such as Mongrel, Thin, or Unicorn
parses HTTP and creates a Rack env hash directly, while nack (JavaScript side)
uses node.js' HTTP parser and builds that Rack env hash encoded in JSON,
then nack (Ruby side) parses that JSON to build the real Rack env hash.

We can think of this as previously use HTTP to communicate in between
web servers and application servers, now we can use JSON to communicate
instead. It's really simple, and could be implemented if not in a few
minutes, but in a few hours. (of course, might have bugs in such a rush.)

Now we can benchmark (Nginx +) node.js and (Niginx +) Unicorn
with the same real world web application!

p.s. nack is written in Ruby and CoffeeScript, not JavaScript!
Die! JavaScript...

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0