views:

215

answers:

5

Hi there,

I've a particularly long operation that is going to get run when a user presses a button on an interface and I'm wondering what would be the best way to indicate this back to the client.

The operation is populating a fact table for a number of years worth of data which will take roughly 20 minutes so I'm not intending the interface to be synchronous. Even though it is generating large quantities of data server side, I'd still like everything to remain responsive since the data for the month the user is currently viewing will be updated fairly quickly which isn't a problem.

I thought about setting a session variable after the operation has completed and polling for that session variable. Is this a feasible way to do such a thing? However, I'm particularly concerned about the user navigating away/closing their browser and then all status about the long running job is lost.

Would it be better to perhaps insert a record somewhere lodging the processing record when it has started and finished. Then create some other sort of interface so the user (or users) can monitor the jobs that are currently executing/finished/failed?

Has anyone any resources I could look at?

How'd you do it?

+4  A: 

The server side portion of code should spawn or communicate with a process that lives outside the web server. Using web page code to run tasks that should be handled by a daemon is just sloppy work.

Spencer Ruport
So I'd essentially have to invoke exec() with some sort of script + passed parameters to handle the table generation? That doesn't sound particular pretty either :/.
Gavin Gilmour
You're right. Given the choice between the two I prefer to have a daemon constantly running that's checking for work. The script should issue some work to the daemon (usually though some db records) and then the daemon picks up on it soon thereafter. Of course, creating a service takes quite a bit more time so spawning a process is sometimes the simpler, though somewhat tacky, approach.
Spencer Ruport
Hi, cheers for the response. I ended up building a rough dameon to check a table for records and act on them. I'll probably be cronning it up to run at a regular interval to save any messy communication between the two.
Gavin Gilmour
A: 

Session are not that realible, I would probably design some sort of tasks list. So I can keep records of tasks per user. With this design I will be able to show "done" tasks, to keep user aware.

Also I will move long operation out of the worker process. This is required because web-servers could be restrated.

And, yes, I will request status every dozens of seconds from server with ajax calls.

Mike Chaliy
A: 

You can have JS timer that periodically pings your server to see if any jobs are done. If user goes away and comes back you restart the timer. When job is done you indicate that to the user so they can click on the link and open the report (I would not recommend forcefully load something though it can be done)

DroidIn.net
A: 

From my experience the best way to do this is saving on the server side which reports are running for each users, and their statuses. The client would then poll this status periodically. Basically, instead of checkStatusOf(int session), have the client ask the server of getRunningJobsFor(int userId) returning all running jobs and statuses.

OmerGertel
+1  A: 

You can't expect them to hang around for 20 minutes. Even the most cooperative users in the world are bound to go off and do something else, forget, and close the window. Allowing such long connection times screws up any chance of a sensible HTTP timeout and leaves you open to trivial DOS too.

As Spencer suggests, use the first request to start a process which is independent of the http request, pass an id back in the AJAX response, store the id in the session or in a DB against that user, or whatever you want. The user can then do whatever they want and it won't interrupt the task. The id can be used to poll for status. If you save it to a DB, the user can log off, clear their cookies, and when they log back in you will still be able to retrieve the status of the task.

Draemon
Thanks for the response. I went with this.
Gavin Gilmour