Asynchronous jobs in Rails

Hi,

I have been researching about this for couple of days now. My rails
application needs to send email notifications to large number of
customers. Before sending the message, application customizes content
for each recipient. The requirement compels me to call ActionMailer's
deliver method for each email address.

I would like to send notifications asynchronously. I looked into
backgroundRB. I have been playing around with it for almost two days
and I can't get it working on cygwin. However, my main concern is the
poor performance of backgroundRB for moderate or high scalability
needs.

I also looked into Threads in ruby. Since rails is single threaded and
especially ActiveRecord is not thread safe, I dropped that idea too.

What are the options generally used for asynchronous jobs in rails ?
From google search I find only two options mentioned above. Please
tell me your experience with either of them. Is there any other
solution that I have overlooked ?

Thank you!

We've used BackgroundRb for our light-to-this-point asynchronous
processing needs. It was a pain in the butt to get working initially
(and we can still only run it on our Linux boxes, not on Windows), but
I've perceived it to be probably the most frequently used asynchronous
solution for Rails, so we're going to go with it until we can't.
Though it's a memory and process hog, I don't think there would be
trouble sending many mails with it, as long as its running on a
machine with a lot of memory, and as long as those mails aren't spam
sent to me inbox. :slight_smile:

Another popular asynchronous option is to combine a queuing system
with rake tasks that run jobs as they are put in the queue. Starling
is a fairly reliable and easy to setup queuing solution developed and
used by the folks at Twitter. You can use it with Workling to
automatically process your tasks, or you can write a rake task that
runs via crontab and checks for jobs to run on some timed interval.

There's some documentation on setting up Starling on my blog.

Bill
http://www.williambharding.com/blog

Thanks for you response. I was thinking about Amazon queue service and
if that might help me here. Our production servers are on linux but my
dev machine ( to my dismay) is a windows machine. BackgroundRB seems
promising as along as I am able to get it to run.

Hey Procyon,

I've recently set up backgroundrb to work with my app and it performs
an emailing function as well.

Althought I haven't put it through a rigorous stress test yet, one
test that I did conduct was setting my Worker method to run every 1
second and having it process 200 emails each time.

The server was a 512mb slice from slicehost. It has 2 rails sites on
it right now. At normal operations (with bgrb stopped), it has about
403mb free and 108mb used. During my test for about 5 minutes, the
server memory usage went to around 200mb free. I was using sendmail to
send off the emails... and I didn't check how much of the memory usage
that was using. I should also note that the Worker code did not use
the thread_pool feature so that might help bring memory usage down as
well.

For my purpose, I think I won't be sending more than 1000 emails per
hour and so it looks like it will be able to serve my needs easily
unless my traffic goes crazy like FaceStat.

Hope this helps.

~ mel

PS: If you need any help with getting things set up, feel free to IM
me on Gtalk at melvin @-AT=@ volcanicmarketing.com. I'm no expert with
it but I'll try to help

You should also check out Starling with the Workling plugin. I found
it to be a much easier, robust, and efficient method for doing
background processing. Check out http://davedupre.com/2008/03/25/ruby-background-tasks-with-starling/
for a series I did after not being pleased with how backgroundrb was
working.

We've used BackgroundRb for our light-to-this-point asynchronous
processing needs. It was a pain in the butt to get working initially
(and we can still only run it on our Linux boxes, not on Windows), but
I've perceived it to be probably the most frequently used asynchronous
solution for Rails, so we're going to go with it until we can't.
Though it's a memory and process hog, I don't think there would be
trouble sending many mails with it, as long as its running on a
machine with a lot of memory, and as long as those mails aren't spam
sent to me inbox. :slight_smile:

I am afraid, that has changed unless you are running old svn version
of backgroundrb:

http://gnufied.org/2008/05/21/bleeding-edge-version-of-backgroundrb-for-better-memory-usage/

Many users have found git version to be quite stable and since now
bdrb uses fork and exec ( meaning it replaces old process image with
new one), there is no sharing of resources between workers, which used
to prevent garbage collection of objects, which were allocated before
fork. Its not a problem of bdrb per se, since Ruby interpretor is
known to be not COW(copy on write) friendly (for uninitiated, it means
that, in ruby, when you fork, all the objects in scope have a bit set
in them, so as they get copied in forked process. This is fine, but
this prevents, those objects from garbage collected. Ideally, it
should copy only when an object's value is changed in child , hence
copy on write . But Ruby doesn't do that. You will find plenty of
material about this on internet)

Github version of bdrb uses fork and exec, and hence it means that,
objects are no longer shared and hence garbage collection can work as
usual. In fact, if you want access to rails environment, this is as
much as lean and thin you can get. You can't have your cake and eat it
too.