A project I am working on required a background process to check and update subscriptions nightly, and send out billing emails to users with expiring subscriptions. I decided to use BackgrounDRb, a plugin perfectly suited for this task.
Setting up:
BackgronDRb runs as a separate server, but is just a process with access to all your Rails models.
<br /><br /> # Generate a worker model:<br /><br /> script/generate worker billing<br /><br />
This generates a worker called BillingWorker in lib/workers. My billing_worker.rb goes like this:
<br /><br /> class BillingWorker < BackgrounDRb::MetaWorker</p><br /> <p>set_worker_name :billing_worker</p><br /> <p>def create(args=nil)</p><br /> <p>end</p><br /> <p>def do_nightly_updates<br /><br /> Subscription.run_notify<br /><br /> end</p><br /> <p>
</p><br /> <p>#In subscription.rb:<br /><br /> class Subscription < ActiveRecord::Base<br /><br /> def notify!<br /><br /> UserMailer.deliver_expiring_subscription_notification(subscription)<br /><br /> end</p><br /> <p>def self.run_notify<br /><br /> find( :all, :conditions =&amp;amp;amp;gt; ['send_notice=?', true] ).each(&amp;amp;amp;amp;:notify!)<br /><br /> end<br /><br /> end<br /><br />
To trigger the worker process to perform its task at 12:01 a.m. every day, my background.yml reads:
<br /><br /> :backgroundrb:<br /><br /> :ip: 0.0.0.0<br /><br /> :port: 11006<br /><br /> :schedules:<br /><br /> :billing_worker:<br /><br /> :do_nightly_updates:<br /><br /> # Trigger this action at 12:01 a.m. every day<br /><br /> :trigger_args: 0 1 0 * * * *<br /><br />
Re the BackgrounDRb cron trigger, here’s a snippet from the plugin docs :
Note that the initial field in the BackgrounDRb cron trigger specifies seconds, not minutes as with Unix-cron. The fields (which can be an asterisk, meaning all valid patterns) are:
<br /><br /> sec[0,59] min[0,59], hour[0,23], day[1,31], month[1,12], weekday[0,6], year</p><br /> <p># The syntax pretty much follows Unix-cron. The following will trigger on the first hour and the thirtieth minute every day:<br /><br /> 0 30 1 * * * *</p><br /> <p># The following will trigger the specified method every 10 seconds:<br /><br /> */10 * * * * * *</p><br /> <p># The following will trigger the specified method every 1 hour:<br /><br /> 0 0 * * * * *<br /><br />
(Aside) If you’re developing on a Mac like I am, you may want to use
</p><br /> <p>:ip: 0.0.0.0</p><br /> <p># instead of<br /><br /> :ip: localhost<br /><br />
for things to run smoothly
Run it!
Fire up two Terminal windows, one to start and stop the BackgrounDRb server, and the other one to monitor the log file:
<br /><br /> script/backgroundrb start<br /><br />
Everything is hunky-dory right now, I just need to do two further tasks:
1. Write specs for my worker model – I can’t seem to mock my model correctly, I keep getting undefined constants errors when running autotest.
2. Have a BackgrounDRb process upload images to S3 in the background using Paperclip.


0 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.