Workers – New Features

Recently I added a number of features to my Workers gem:

The Task and TaskGroup classes make it even easier to parallelize expensive computations (and blocking IO operations) using background threads.  They build on top of worker pools and standardize on various features such as success/failure handling, delayed execution, and arguments.

Parallel Map is syntactic sugar built on top of tasks and task groups.  It works very similar to Ruby’s standard Array#map method except each element is mapped in parallel.

Pools are now dynamically resizable.  The long term vision for this feature is to experiment with auto-resizing algorithms that adapt to an applications load.  In the short term it is mostly useful for quickly changing the size of the default pool (currently set to 20 workers) without having to create a new one.

Networking for Tribe

Recently I put together two new Ruby gems called Tribe EM and Tribe EM AMF Socket.  Both gems build on top of my Tribe gem.

Tribe EM bridges the gap between Tribe and EventMachine.  Currently it provides basic TCP server functionality for Tribe actors.  My intent is to use this as a base for implementing higher-level protocols such as HTTP.

Tribe EM AMF Socket is a wrapper around my existing AMF Socket – Ruby gem.  Currently it only supports messages and not requests (RPC).  I believe this to be a reasonable limitation for now since AMF Socket messages fit in very well with Tribe’s asynchronous messaging system.

One key difference between the two gems is what I refer to as native vs wrapper implementations:

Native: The Tribe::EM::Connection class is considered native since it pushes the higher level protocol implementation onto the actor threads.  This results in greater scalability since actors take advantage of multi-core systems (especially on JRuby).

Wrapper: The Tribe::EM::AmfSocket::Connection class is considered a wrapper since it wraps the AMF Socket gem for use with Tribe.  This means that a lot of work (serialization, deserialization, framing, keep alives, etc) are all performed on the EventMachine thread.  The result is lower performance than a native implementation, but less coding since I can reuse the existing Ruby implementation of AMF Socket.

Both gem are designed to be easily customized.  Feel free to contact me with your custom protocol implementations so that I can add them to the Tribe EM homepage.

Workers and Tribe – Ruby threading simplified

Recently I’ve created two new Ruby gems known as Workers and Tribe.

The Workers gem turns low-level operating system threads into simple to use event-driven workers and worker pools.  This allows you to focus on message passing instead of complex thread management.  As an added bonus, it includes a timer system that can tell your workers to execute work in the future.

The Tribe gem builds on top of Workers in order to implement the actor model. It specifically focuses on event-driven actors such that each thread manages one or more actors.  This way the system can support many more actors than is possible with implementations that force a 1:1 thread to actor relationship.  A simple benchmark demonstrating one million actors using 20 threads can be found on the performance wiki page.

Both gems have been tested with MRI Ruby 1.9.3 and JRuby 1.7.  Due to MRI’s thread limitations, it is highly recommended that you use JRuby if you are concerned about multi-core CPU performance.

Inspiration comes from Erlang, Scala, Akka, and Celluloid

 

AMF Socket – Easy Actionscript Networking

Recently, I created AMF Socket.

AMF Socket is a bi-directional remote procedure call (RPC) system for Adobe Actionscript programs. This library aims to make high quality and free RPC accessible to all of the Flash platforms (web, mobile, and desktop). Using this library you can easily add event driven network functionality to your Flash applications without having to deal with the low level details. High performance and low latency is accomplished through the use of persistent TCP/IP sockets and Flash’s native serialization format (AMF). Due to the use of AMF, you can send primitives, hashes, arrays, and even your custom classes over the network.  AMF Socket tries to be the “easy button” for Flash networking by hiding as many details as possible.

I’ve also created a Ruby implementation for the server side.  Implementations for other languages should be fairly staright forward and I welcome them.  Feel free to contact me if you are interested in creating one.

 

Spinal Tap – admin console for Ruby processes

Today I released a very early/alpha version of Spinal Tap.  I deal with a lot of long running Ruby processes (crons, daemons, etc) and I occassionally need to debug them while they are running.  Thus Spinal Tap was born.  The future vision includes statistics tracking, custom defined commands, and much more.  Think of it as a backdoor into your Ruby processes :-)  Thanks go to my good friend Scott McCarty for brainstorming the long term vision of the project.

Torquebox Investigation

My good friend Scott McCarty mentioned that I should checkout the Torquebox project and so I spent my morning with it.  Below is a summary of my experience.

Installation

 You have to choose one of two install paths:

  • The large download that contains everything you need (JRuby, Torquebox, etc).
  • Manual instalation of JRuby and then the torquebox-server gem.

I went with the gem option since I already had Jruby installed and I have an existing Rails app that is Jruby compatible.  There is only one area I got hung up on.  JRuby supports both the old (1.8) and new (1.9) ruby syntax.  All of my new projects use 1.9, but the current version of JRuby (1.6.7) defaults to 1.8 syntax.  The fix was simple once I learned how deployment descriptors work in Torquebox.  I had to drop the below torquebox.rb in my Rail’s root folder:

  TorqueBox.configure do
    ruby do
      version "1.9"
    end
  end

Workflow

Workflow for developing a Torquebox enhanced Rails app is the same as a normal Rails one.  The only difference is I had to replace running “rails server” with “torquebox deploy” and “torquebox run”.  I still need to run “rails console” in a separate terminal.  Overall the Torquebox documentation is high quality and made it more or less painless.

Rails Console

The Rails console is slower to startup with JRuby.  I’ve found a number of useful recommendations, but none of them completely fix the problem.  My best recommendation is to make sure you keep your code compatible with the “reload!” method and avoid restarts.

Testing

Next on my list of things to do is to figure out if people have Spork and Guard working with JRuby.  Using this combo of gems I have a really nice continuous testing solution with C Ruby.  I would hate to give this up with Torquebox.

Vim

One unexpected side effect is that various commands in Vim are slow due to switching to JRuby. Vim appears to stall for a short, but noticable time when some plugins fire up JRuby processes.  I use a highly customized Vim using the Janus distribution.

New Rails Projects

I haven’t tried it, but I noticed that Torquebox comes with a command for generating new apps.  My guess is this is the way to go since it probably generates a Rails app that is fully patched for JRuby and Torquebox.

Converting Existing Rails Projects

My project was originally built for C ruby 1.9, MySQL, and Rails 3.2.  This meant I had to do my normal hacking on Gemfile and database.yml to make it simultaneously compatible with both C Ruby and JRuby.  Fortunately for me, all of my gems were compatible with JRuby including a few that integrate with C code via FFI.

Deployment

Unfortunately I didn’t take this experiment to the deployment phase. The documendation and packages for Fedora/RHEL look fairly straightforward for those with Linux sysadmin skills. It will most likely help to read over the JBoss documentation too. You can also deploy to Red Hat’s Openshift cloud.

The Real Benefits

The real benefit of Torquebox is how it exposes the JBoss feature set to a standard Rails app.  In some cases it remaps standard Rails APIs to JBoss (like with caching and sessions).  Other features (such as job scheduling and messaging) aren’t built into Rails so I believe they wrote wrappers.  Effectively they are giving you a more complete platform for building complex apps instead of you having to assemble one yourself from open source components.  Of course you can also pay Red Hat for support which is a huge win for some companies.  The JBoss, Torquebox, and JRuby teams are sponsored by Red Hat so you know you’ll be well taken care of.