JRuby at Webpop

The nice folks at EngineYard invited me to do a presentation on our use of JRuby at Webpop at the recent SF Bay Area JRuby Meetup.

While I could post my slides here, they'll probably not be of much use to anyone, since the meat of the talk was in the code examples. So instead I've uploaded the examples to my Github account and made this little writeup of the talk.

Webpop is a Cloud hosted CMS. You could think of it as a Heroku or App Engine for web designers, where we take care of all the operational stuff of handling peaks in traffic, uptime, security and performance while the designers can focus on being creative and making great sites for their clients.

Rhino At Webpop

One problem that almost all hosted CMSs suffer from is lack of extensibility. When you need something that's not included in the CMS, you're simply out of luck. When we set out to make Webpop we wanted to tackle this problem from the start.

Our solution has been to embed a javascript extension engine at the very core of Webpop, allowing people to write extensions to the CMS in server-side javascript.

To handle the execution of non-trusted javascript on our servers in a safe and controlable way, we turned to Rhino.

Rhino is a Javascript implementation written entirely in Java, running on the JVM. This makes it very easy to hook into through JRuby's great Java interoperability.

I gave 3 simple examples at the meetup and the code is now up at Github

The first example shows just how simple it is to execute javascript from JRuby:

This should be enough to get started with JRuby and Rhino. There are two more examples in the repository, showing how to get Rhino to execute a callback for every 100 instructions (handy for monitoring execution time and resource use) and how to expose JRuby methods to the javascripts.

Akka at Webpop

At Webpop we do a lot of background processing tasks. Whenever we want something done in the background we drop a message in a RabbitMQ queue and let a worker somewhere consume it.

Initially our workers were based on Minion but, since MRI has a global interpreter lock, the only way to effectively run tasks in parallel was to fire up several Minions. Since we wanted to be able to use our Rails Models in our background jobs, this effectively meant having to load a full Rails environment into memory for each parallel job. Not optimal!

Akka is a really cool Scala based library, bringing an Erlangish concurrency model to the JVM, complete with supervision trees, distributed actors, an STM implementation and more.

Once again JRuby makes it easy to hook into all of this.

I've uploaded 3 examples to Github. The third one is where it really starts getting interesting.

This example demonstrates using Akka's AMQP client to setup 10 thread-based actors to consume messages from a RabbitMQ queue called "fetch.url".

Akka comes with a bunch of different dispatchers, representing different concurrency strategies. In this case we're using the brute force aproach of giving each actor it's own OS thread. Akka will handle the message passing between the threads for us and will automatically restart any actor that crashes while processing a message (in this case we let the consumer auto acknowledge the message, so the message will be lost, but it's also an option to handle the ack manually and let the message drop back to the message queue if processing fails).

This obviously barely touches on what Akka can do but it's already a really handy way to load up a bunch of actor based threads with just one copy of a full Rails environment in memory.

JRuby makes using these libraries from Ruby extremely easy and makes it possible to tap into concurrency models that are normally beyond the reach of the popular scripting lanauges.

comments powered by Disqus