views:

52

answers:

1

I have a controller that generates HTML, XML, and CSV reports. The queries used for these reports take over a minute to return their result.

What is the best approach to run these tasks in the background and then return the result to the user? I have looked into Backgroundrb. Is there anything more basic for my needs?

+3  A: 

You could look at using DelayedJob to perform those queries for you, and have an additional table called "NotificationQueue". When a job is finished (with its resultset), store the resultset and the User ID of the person who made that query in the NotificationQueue table. then on every page load (and, if you like, every 15-20 seconds), poll that database and see if there are any completed queries.

DelayedJob is really great because you write your code as if it wasn't going to be a delayed job, and just change the code to do the following:

#Your method
Query.do_something(params)

#Change to
Query.send_later(:do_something, params)

We use it all the time at work, and it works great.

Mike Trpcic
I just *adore* this design.
Jonathan Julian
DelayedJob looks promising, but how do you store the result set when using ActiveRecord?
Trevor
DelayedJob basically runs a copy of your application. It has access to your database, so when you call delayed job, it says, "Ok, run this piece of code, with this data". It'll save to the database just like a regular function would.
Mike Trpcic
If the query will be returning data to the user (and not saving anything to the database), how can I save that result set after the job/query has finished? If my query returns 10MB of data to be sent to the user, how do I approach that? Thanks.
Trevor
In that case, you'd want to create a new database table to act as a Queuing system. We'll call it "Queue". This queue could have three columns, "id", "user_id", and "data". Put the data in the "data" column, and the proper ID in the "user_id" column. Then on every appropriate page load, query that database. "SELECT * FROM queue WHERE user_id = 10". Now you can display all the finished data to the user.
Mike Trpcic
If you don't need to persist the results, you can store them in memcache and ajax them into your web page.
Scott
@Scott: That seems like it's a little bit overkill. My method is standard rails, and only persists them until they're used (just delete them from the database after). It's also simple to create an AJAX listener that hit an action that queries that table.
Mike Trpcic