BackgrounDRb offers seemless integration with rails. You can invoke random tasks defined in your workers from rails. You can pass arguments, collect results, monitor status of workers and other statistics.
BackgrounDRb offers two sets of APIs for interacting with workers from rails. One is newer, slicker
set and other is older legacy compatibility API. 1.0.3 version made a departure and implemented newer
cleaner APIs, we will discuss them first, before getting acquinted with older API. Also, no matter
which API you are using MiddleMan
is the proxy object that lets you handle all this.
Invoke an asynchronous task on a worker :
Following snippet will invoke method some_task
with argument data
in foo_worker
. Also, method will
be invoked asychrounously and Rails won’t wait for result from BackgrounDRb server.
worker = MiddleMan.worker(:foo_worker) worker.some_task(data)
Here, I would like to illustrate a point that contrary to general percenption, since some_task
method is being
executed asyhcrounously, don’t expect any meaningful return values from second line.
When you invoke MiddleMan.worker(:foo_worker)
it returns a worker proxy, hence you can combine above two lines in
one as follows:
MiddleMan.worker(:foo_worker,<optional_job_key>).some_task(data)
Above snippet also demonstrates that, if your worker was started with a job_key
you can use it to
get correct proper worker proxy.
Invoke a method on worker and get results :
Following snippet will invoke method some_task
with argument data
in foo_worker
. Also, method block
until BackgrounDRb server returns a result.
worker = MiddleMan.worker(:foo_worker) result = worker.some_task(data,true)
As illustrated above, you can use job_key
or make them in single line too. When you are invoking a method
on your worker first optional argument will be passed to your worker method and second optional argument true|false
indicates whether we should wait for result from BackgrounDRb server or not.
Fetch Status/Result Objects of a worker :
If you are using register_status
in your worker code to store status/result objects, you can retrieve them from
rails using:
status_obj = MiddleMan.worker(:foo_worker).ask_status
You can as usual use job_key
if worker was started with a job_key.
You can query status/result objects of all workers in one shot. For example, in your controller:
def ask_status t_response = MiddleMan.query_all_workers running_workers = t_response.map { |key,value| "#{key} = #{value}"}.join(',') render :text => running_workers end
Start a Worker :
To start a worker from rails:
used_job_key = MiddleMan.new_worker(:worker => :foo_worker,\ :job_key => "my_secret_job_key")
new_worker
will always return job_key
generated for the worker. It will be same as job_key
passed while creating the
worker and can be reused to invoke further tasks on the same worker or for deleting the worker.
Important thing to be kept in mind is, when you are creating a worker using above approach, you
must use a unique job_key
while starting the worker. Also, while invoking any of the other methods
like ask_status
, worker_info
or one of the worker methods, you must use job_key
.
Also another complicated example of starting a worker will be:
MiddleMan.new_worker(:worker => :error_worker, :job_key => :hello_world,\ :data => "wow_man",:schedule => \ { :hello_world => { :trigger_args => "*/5 * * * * * *",\ :data => "hello_world" }})
Above code will start error_worker
with job_key
and will pass argument :data
to create
method of the worker. Worker will be scheduled to run hello_world
method every 5 seconds with argument
specified in :data
.
Worker Statistics:
You can get worker specific information using:
MiddleMan.worker(:foo_worker).worker_info
The return value will look something like:
{:worker=>:foo_worker, :status=>:running, :job_key=>"hello"}
Information about all currently running workers can be obtained using:
MiddleMan.all_worker_infoReturn value will look like:
[{:worker=>:foo_worker, :status=>:running, :job_key=>"hello"}, \ {:worker=>:foo_worker, :status=>:running, :job_key=>""}]