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.
Update::
There was a small error in BackgrounDRb startup script, because of which you may not be
able to start BackgrounDRb server. Its been fixed in git and svn trunks. Hence, make sure
that you are running latest code from git or svn trunks. Also, after checking out code from repo,
don’t forget to remove old ‘backgroundrb’ script from script directory of rails application
and run rake backgroundrb:setup
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
After getting the plugin, you must configure it for use. BackgrounDRb comes with a rake task for automating plugin configuration. Before running rake task, remove if any old ‘backgroundrb’ script is there in script folder of your rails app after that run, following command from root directory of your rails application, after installation:
rake backgroundrb:setup
Above Command does following things :
- Creates a config file
backgroundrb.ymlin config directory of your rails application. - Creates
RAILS_ROOT/lib/workersdirectory for keeping BackgrounDRb workers in one place. - Creates
RAILS_ROOT/test/bdrb_test_helper.rbas a test helper for your workers
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: false # load models eagerly :debug_log: false # disable log workers and other logging :schedules: # optional task scheduling : # look in scheduling section
lazy_load option should be false 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.
It is possible to set options depending on the environment:
:backgroundrb:
:ip: 0.0.0.0
:development:
:backgroundrb:
:port: 11111 # use port 11111
:log: foreground # foreground mode,print log messages on console
:production:
:backgroundrb:
:port: 22222 # use port 22222
:lazy_load: true # do not load models eagerly
:debug_log: false # disable log workers and other logging
This will cause script/backgroundrb to use port 11111 and to log to foreground under
development environment and script/backgroundrb -e production to use port 22222,
lazy_load and no debug_log under production environment. The ip 0.0.0.0 is used in all
environments.
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
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.worker(:billing_worker).charge_customer(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