Tag: spring

Ruby on Rails vs. Java, part 1

Posted on February 17, 2008

One of the components of the system developed here at Blackwhale is an fairly advanced web mail/campaigning and analytics system. The first iteration of that component was fully implemented in Ruby on Rails. Writing the front end was fairly easy and fast, a perfect opportunity for Rails to display its strengths. On the back end and communication part on the other hand I stumbled into various problems:

  • Compared to PHP, Python or Java there are just too few communication libraries. And even the libraries that exist are lacking fundamental features and almost all of them come without useable documentation. That there is no encryption (SSL or TLS) support in the whole Ruby 1.8 mail libraries is an outright shame. The IMAP library is so clumsy that a web company sells their own (still not perfect library) through their online store and they seem to make a good buck with it.

    On the Java side is just a completly different picture: Lots of libraries, even documented ones are available. After having to touch the TMail (rail’s MIME mail handler library) API using javax.mail is a heavenly gift. And it seems that the TMail generated MIME messages were invalid in a couple of cases. Not the best feature of a support library. Also the chance of finding unsolved known bugs and errors seems to be lot smaller in Java.

  • This brings me to another point: I might change my opinion on Java’s constraints on its users. Java tries hard to prevent errors (i.e. the forced exception catching). I always thought that that took too many stylish possibilities away from the user, but by now I must confess that I think that this is exactly what I want from something that I’m using on the network side. I’m a lazy programmer, I want to be reminded and forced to write secure and stable code. This is the quite different to Ruby and Rails ‘make it easy for the programmer’ attitude.
  • Background processing is hard. As Ruby on Rails is not multi-thread safe you can’t just spawn a thread if you need to perform some longer running task. Another disadvantage of using a single-process model is that the long running request will occupy one rails worker (i.e. rails cluster process) until it has finished - in our case that costs us around 60MB of memory per long running request, even if it is just waiting for some simple SMTP feedback. If you can find a situation where you can delay the execution of a network related task (and if you don’t you’re not thinking) for two seconds, 6 requests per seconds will DoS a standard rails cluster.

    The only solution that’s actually usable is BackgroundRb. But projects that just change their background communication system just don’t sound to production-grade ready for me. Also the admin start/stop scripts for their background server didn’t work too well for me.

  • For a language that interferes it’s object’s attribute types directly from the database the ActiveRecord layer is weak. Don’t get me wrong, I understand that the Simplicity is needed to make it easily usable but I ran into various situations where I’d love to have a full blown ORM behind me. One feature that is needed quite often by our application is inheritance. ActiveRecord only offers single table inheritance, and even there you have to make sure that each row is valid (ActiveRecord should have all needed information to do that by itself BTW) or you will run into problems later on. One problem is, that it tries to abstract too much functionality away from the database while not provided as advanced interfaces by itself. Data integrity handling? Abstracted away by rails, so all databases can be used the same. The drawback is, that the data constraints and relations are fully handled by rails and not passed on to the database. Any process that might produce invalid data (e.g. a faulty rails component) might corrupt the data. Rails is able to handle that cases by itself (due to ducktyping and very few default checks), but access that data with any other framework and it blows up directly into your face.
  • Transaction handling. Just try it. Then cry. Also I’m not sure if Transaction handling is even done on database level or in Rails (as done with constraints). If the later is true, it’s acutally not worth anything as soon as more processes try to access the database.

The library and documentation problems where the main reason for me to reimplement the mailing and campaigning backend in Java. The front end is still a Rails application — which is exactly what Rails is for. As I’m no friend of blown-up EJB based solutions I’ve choosen a simple Spring and JPA based solution for that problem.

I’m currently testing the last features and replacing the Ruby code part by part. As soon as I’ve done that another blog post will examine the two implementations, how much time was spent on coding them and how they perform when compared to each other.