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.
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. 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.yml
in config directory of your rails application. - Creates
RAILS_ROOT/lib/workers
direcotry for keeping BackgrounDRb workers in one place. - Creates
RAILS_ROOT/test/bdrb_test_helper.rb
as 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: 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.
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.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