Thursday, June 15, 2006

Mongrel in JRuby?

I'm going to try to post more frequent, less-verbose entries to break up the time between longer articles. This is the first.

For those of you unfamiliar with it, Mongrel is a (mostly) Ruby HTTP 1.1 server, designed to escape the perils of cgi/fcgi/scgi when running web frameworks like Rails or Camping. From what I hear it's very fast and very promising. Think of it as a Ruby equivalent to Java's servlet/web containers like Jetty and Tomcat.

Deploying Rails apps under JRuby currently has only two reasonable outlets:

- You can wrap all the Rails-dispatching logic into a servlet, deploying as you would a web application.
- You can (mostly) run the "server" script, which starts up Rails in WEBrick, Ruby's builtin lightweight server framework.

The first option would obviously provide the best integration with existing Java code and infrastructure. The second is good for development-time testing.

However, with JRuby rapidly becoming production-usable, there will be many folks who want a third option: deploying Rails--just Rails--in a production environment without a meaty servlet engine. For Ruby, that's where Mongrel comes in.

Mongrel is by the developer's own admission "mostly" Ruby code. The one big area where it is not Ruby is in its HTTP parser library (there's also a native ternary search tree, but that's no big deal to reimplement). Using Mongrel, require 'http11' pulls in a C-based HTTP 1.1 parser and related utilities. Ruby is notoriously slow for parsing work, so this native code is not unreasonable. However, it would be a barrier to running Mongrel within JRuby; we would need our own native implementation of the http11 library.

So, any takers? If I had a nickle for every JRuby sub-project I want to work on I'd have a fistful of nickles. This one will probably be pretty far back in the queue.

Known possibilities for lightweight HTTP 1.1 support (really all that's needed for Mongrel is an HTTP1.1 library, but that can probably be used alone):

- Jetty
- Simple

For those of you that say "Why not just wire Rails into [Tomcat|Jetty|Simple] and be done with it" I have this answer: Rubyists are not particularly fond of Java libraries. My aim of late is working toward supporting both Ruby/Java folks who will happily marry the two and pure Ruby folks that simply want another runtime to use. Mongrel is bound to become a very popular choice for web serving Ruby applications, and we would be remiss if we did not attempt to support it.

6 comments:

Ola Bini said...

Support Mongrel would definitely be interesting, and I can think of other uses for a good http/1.1 parsing library in Java. Especially since it seems Rails is moving away to Mongrel as the base web server, instead of WEBrick. So, not prio 1 to get it working, but maybe a 3 or something. How big is the library, btw?

Charles Oliver Nutter said...

If you're talking about the http11 library in Mongrel, it looks like about 40k of C code. The TST adds another 15k or so. The Ruby portion of Mongrel, including all its plugins for Rails, Camping, etc, tallies up to about 65k.

Scott L. said...

I've been playing around with Jaminid. It was (still is) my desire to create a simple, no frills http server for a JRuby project. I've been asking myself lately if I should just wait for webrick support in JRuby.

Fortunately, I've only done a few things with Jaminid - I haven't had the time lately as I'm in the middle of some family medical problems - that's been settling down.

I'll take a look at Mongrel. I guess what you're thinking is that we replace the C portion with a Java library, yes? I'm no Java programmer but I know my way around Eclipse pretty well and I can probably get us a starter kit going.

Scott

Charles Oliver Nutter said...

Scott: That's exactly what I'm thinking. There's not all that much C code, and of course most of the networking stuff should already be built into JRuby (though bits and pieces of that still need some work too). It shouldn't be terribly difficult to get Mongrel working at a basic level given projects like Jaminid, Jetty, Simple, and others that already provide some of the necessary utilities.

Jaminid looks promising, as does Mongrel. I think it's valid to want to support both Java and Ruby servers in JRuby, since we would love for JRuby to be usable as a general-purpose runtime.

Zed A. Shaw said...

Look at http://mongrel.rubyforge.org/coverage/ and see that it's 1278 lines of code for the core ruby library. Runinng wc -l *.c *.h in the ext/http11 directory gives 2231. If you take out the http_parser.c file (since it's generated from the .rl file) that brings it down to 1403 lines of C. That's not including comments (of which there's less than the Ruby code).

So you're actually looking at a "whopping" 2681 lines of actual code (ruby, C, Ragel) that you'd have to deal with. I've seen ant scripts that are longer than that. And don't get me started about struts configs.

There's a few example files, and some plugins of which you only need GemPlugins to run Mongrel--and that's tiny.

So, saying "65k of code" is really misleading. First time I and a few others read that we thought you were saying *lines* of code. Just wanted to set the record straight so people didn't get discouraged.

Good luck getting it all to run under JRuby. I seriously think you guys should check out Simple instead though. It's very much like Mongrel in that you could trim it down to a core library that's tiny and embed it easily. My experience has been that all religion about "java libraries" will go out the window if people who use JRuby can run whatever you cook up without any fuss. As long as they don't have to run a Maven repository grab to get 1000 billion .jar files of all different versions then they'll be happy.

Charles Oliver Nutter said...

Zed: I figured the numbers were small, but that's impressively small.

I agree that Simple would be, well, simpler, and I think that a Simple-based web-frontend for JRuby/Rails/Camping would be extremely nice to have. I think is should be done, and I'm sure as Rails becomes more and more usable under JRuby, someone will do it.

My intent with the Mongrel angle is to potentially give non-Java-aware Rubyists a way to download JRuby, run "gem install mongrel" and be on their way. This isn't to say that we couldn't package things like Simple into jars, but there's getting to be a volume of work based on doing things "the Ruby way". If we can keep the barriers to entry low, we'll get more Ruby folks interested in trying JRuby out.

So I guess in summary, all roads lead to good things...having many choices is a good thing.