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.4 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.7 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.4 BackgrounDRb development has moved to github. 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://github.com/gnufied/backgroundrb.git 

Also for running git version of BackgrounDRb you will need, git version of packet.

Installation using Piston

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

Configuration

After getting the plugin, you must copy it into your vendor/plugins and then configure it for use. BackgrounDRb comes with a rake task for automating plugin configuration. Before running rake task, remove if any old backgroundrb or load_worker_env.rb script is there in script folder of your rails app after that run, following command from root directory of your rails application:

rake backgroundrb:setup 

Above Command does following things :

After above make sure, that generated migration is ran using:

rake db:migrate 

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
  :debug_log: false # disable log workers and other logging
  :persistent_disabled: false # turn this off if your application doesn't use backgroundrb's persistent/enqueued tasks system
  :persistent_delay: 10 # the time (seconds) between each time backgroundrb checks the database for enqueued tasks
:schedules: # optional task scheduling
  : # look in scheduling section 

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 asychronously one can use:

MiddleMan.worker(:billing_worker).async_charge_customer(:arg => 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