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=>""}]