Introduction

BackgrounDRb is a Ruby job server and scheduler. Its main intent is to be used with Ruby on Rails applications for offloading long-running tasks. Since a Rails application blocks while serving a request it is best to move long-running tasks off into a background process that is divorced from http request/response cycle.

Installation

Installing the dependencies :

As of version 1.0.3 BackgrounDRb depends on chronic and packet gems. Thus lets get started by installing these two gems:

sudo gem install chronic packet 

Please note that, this version of BackgrounDRb needs packet version 0.1.5 or greater, so make sure you have that.

Getting the code from Subversion :

 svn co http://svn.devjavu.com/backgroundrb/trunk 

Installing from Git:

As of version 1.0.3 BackgrounDRb development has moved to gitorious. Above SVN url will always mirror stable releases from Git. However to enjoy latest and greatest of features you can install the plugin from git:

git clone git://gitorious.org/backgroundrb/mainline.git backgroundrb 

Installation using Piston

piston import http://svn.devjavu.com/backgroundrb/trunk/ backgroundrb 

Configuration

After getting the plugin, you must configure it for use. BackgrounDRb comes with a rake task for automating plugin configuration. Run, following command from root directory of your rails application, after installation:

rake backgroundrb:setup 

Above Command does following things :

Configuration Options

A default backgroundrb.yml file looks like this:

:backgroundrb:
  :port: 11006
  :ip: 0.0.0.0 

However, various other configuration options are available. For example, to load production environment in your workers:

:backgroundrb:
  :port: 11006
  :ip: 0.0.0.0 
  :environment: production 

Following file demonstrates other available configuration options:

---
:backgroundrb:
  :port: 11006 # port to start listen
  :ip: localhost # host to listen
  :environment: production # rails environment to load
  :log: foreground # foreground mode,print log messages on console
  :lazy_load: true # do not load models eagerly
  :debug_log: false # disable log workers and other logging 

lazy_load option should be true if you want to pass ActiveRecord model objects around, However, this option is generally not encouraged to use, because if your model makes use of some other ActiveRecord plugin and plugin is not available during load, loading of model will fail. In new version of BackgrounDRb its generally discouraged to pass model objects around, since they are harder to serialize and deserialize.

Workers

Once you are set with initial configuration, you can proceed to create worker and start BackgrounDRb server. To generate a worker:

 ./script/generate worker billing 

Output will look something like:

exists  lib/workers/
create  lib/workers/billing_worker.rb 

And generated worker will look like:

class BillingWorker < BackgrounDRb::MetaWorker
  set_worker_name :billing_worker
  def create(args = nil)
    # method gets called, when new instance of worker is created.                      
   end
  end 

You can define worker specific initialization in create method. Tasks that are to be executed in this worker should be defined as seperate methods. For example:

class BillingWorker < BackgrounDRb::MetaWorker
  set_worker_name :billing_worker
  def create(args = nil)
    # this method is called, when worker is loaded for the first time
  end

  def charge_customer(customer_id = nil)
    logger.info 'charging customer now'
  end
end 

Invoking Tasks

Task charge_customer defined in BillingWorker can be invoked in several ways. To beging with it can be invoked from rails or can be scheduled to execute at particular interval using cron like syntax.

Invoking Task from Rails :

In your Rails controllers you have access to proxy class MiddleMan which can be used to interact with BackgrounDRb server, either from Rails controllers/Models or from Rails console. For example to invoke charge_customer method one can use:

MiddleMan.ask_work(:worker => :billing_worker,\
                :worker_method => :charge_customer,\
                :data => current_customer.id) 

Above code can be also executed from Rails console.

Start the BackgrounDRb server :

You can use:

./script/backgroundrb start 

For more options:

./script/backgroundrb --help 

As documented above, you can use backgroundrb.yml file to load different rails environments, however you can use:

./script/backgroundrb -e development