Some fundamental architectural insights on the Ruby On Rails technology compared to Java

Hi guys,

It's a pleasure for me to join your community mailing list. I am a keen software engineer and experimenter, and happen to investigate and dive into the Ruby language from a couple of weeks. So far i have become familiar with the basics of the syntax and semantics of the language, and, of course, i would like to get to know the Ruby web application framework Rails too. But i enjoy understanding the principles which a software platform relies on, so i would kindly like to ask you some questions about the architecture of the Rails framework that i couldn't find by googling , and would highly appreciate your comments and answers.

Since i come from the JavaSE and JavaEE world, its inevitable for me to try to use the analogy principles between Ruby and Java. In JavaSE we write standalone applications, which we execute over a JVM. In JavaEE we can write web applications, which require a JavaEE web server and container to be deployed in (and of course, underlying the container there is a JVM).

In the classical Ruby scenario, we write standalone applications, which we run on Ruby VM (there are a lot of VMs, implemented in different languages). But when it comes to writing Ruby web applications on Rails, we need some more sophisticated execution environment, such as a Rails web server - WEBrick, Mongrel, etc. Am i already getting it wrong ? Are WEBrick, Mongrel the Ruby analogies of a JavaEE application server, or they are actually something completely different?

Google says that Mongrel is a web server, but isn't Mongrel also executing Ruby code ?

It seems that to execute a Rails application, one needs a Ruby VM and a Ruby web server (and of course, the Rails framework itself installed). But where is the application code executed - directly in the Ruby VM, or inside the Ruby web server (as is in JavaEE: servlets/ JSPs are executed inside the web container) ? That means, what exactly is a Ruby web server doing in the whole picture ? Is it just dispatching HTTP requests to Ruby classes to handle them, i.e. it is only a mediator ? Or is it executing the application code, just like a web container that executes servlet code ?

I would highly appreciate any guidance on this, since so far i cannot answer these questions.

Kindest Regards, Krum.

In that analogy you can think Mongrel is something similar to Tomcat. It is a web server, but one that can also serve Rails applications.

Rails has an entry point to a request, the dispatcher, and Ruby-based web servers are able to execute Rails request because they have code that knows how to call the Rails dispatcher. From that point downwards it is Rails business to handle the request. The contract is that the dispatcher returns a response object that the container manages to send back to the client.

You can also have Apache or Nginx, etc. as front-ends. As you can with a servlet container. In that case you either configure the server to proxy dynamic calls to a set of known mongrels that are running somewhere. Or you can also forget about all that stuff and use an Apache/Nginx module called Passenger which handles everything for you and it just needs that you configure the document root of your Rails application. The latter is the most common production setup nowadays.

That's more or less the picture.

Xavier Noria wrote:

executing Ruby code ?

In that analogy you can think Mongrel is something similar to Tomcat. It is a web server, but one that can also serve Rails applications.

Another important piece of this puzzle when relating to new versions of Rails is Rack:

http://rack.rubyforge.org/

Rails applications for the past sever versions are built on top of Rack. Phusion Passenger is an Apache or Nginx module that supports Rack applications. This includes Rails, but also includes several other ways to build web applications with Ruby.

If you needed something extremely simple you can build web applications with nothing else but Rack.

Example of a functional Rack application:

class HelloWorld   def call(env)     [200, {"Content-Type" => "text/plain"}, ["Hello world!"]]   end end

For more convenience, but without the heft of Rails, there is also Sinatra: http://www.sinatrarb.com/

Hope that clears things up a bit for you.

Thank you guys for your help!

To Xavier's words: So if i am understanding you correctly, Mongrel is capable of transforming HTTP requests to invocations of the Rails dispatcher, and, on the other side, transforming the result from the Rails application back to a HTTP response. So it seems that Mongrel is just a web server, that is a mediator to the Rails application, just like the good old CGI ideology ? Which is also present in the JavaEE case, but with the significant difference that, apart from transforming the HTTP request to a servlet invocation, the web container is THE execution environment, and it handles the complete life cycle of the servlet/JSPs...... In this sense, i see that Mongrel does not handle the life cycle of the Rails component, does it ?

And fianlly, i would also like to ask you some more questions. Consider a typical Rails application, running inside Mongrel. What possibilities do there exist for my Ruby code (of the Rails application) to call/execute Java code ? What is the relation between Mongrel and Java ? From the home page of Mongrel, after i downloaded the Mongrel archive, it seems that it is an application, written in pure Ruby (except for the HTTP parser, which could be written in C or Java). What is the Mongrel <-> Java integration ?

Thank you guys for your help!

To Xavier's words: So if i am understanding you correctly, Mongrel is capable of transforming HTTP requests to invocations of the Rails dispatcher, and, on the other side, transforming the result from the Rails application back to a HTTP response. So it seems that Mongrel is just a web server, that is a mediator to the Rails application, just like the good old CGI ideology ? Which is also present in the JavaEE case, but with the significant difference that, apart from transforming the HTTP request to a servlet invocation, the web container is THE execution environment, and it handles the complete life cycle of the servlet/JSPs...... In this sense, i see that Mongrel does not handle the life cycle of the Rails component, does it ?

what does life cycle mean? The entirety of the request is handled inside the instance of mongrel in question.

And fianlly, i would also like to ask you some more questions. Consider a typical Rails application, running inside Mongrel. What possibilities do there exist for my Ruby code (of the Rails application) to call/execute Java code ? What is the relation between Mongrel and Java ? From the home page of Mongrel, after i downloaded the Mongrel archive, it seems that it is an application, written in pure Ruby (except for the HTTP parser, which could be written in C or Java). What is the Mongrel <-> Java integration ?

I believe that the bits written in C have also been implemented in java too, so you could run mongrel on jruby, which makes calling java code pretty easy (although I believe that people using jruby tend to use options like glassfish rather than mongrel)

Fred

Thank you, Fred.

Could you please elaborate some more on the Mongrel <-> JRuby connection ? If i run Mongrel on JRuby, how does ease me with calling Java code ?

Thanks! Krum.

jruby is written in java (hence the j). Have a look at the jruby docs, they've got a big chunk on java/ruby integration ( http://kenai.com/projects/jruby/pages/CallingJavaFromJRuby )

Fred