tags:

views:

292

answers:

3

Some operation takes much time,

which leads to ajax request to time out,

how to I finish responding to the request fisrt, then continue that operation?

+1  A: 

Spawn a background process and return background process id so user can check on it later via some secret URL.

Eimantas
+1  A: 

Hi,

The ignore_user_abort directive, and ignore_user_abort function are probably what you are looking for : it should allow you to send the response to the browser, and, after that, still run some calculations on your server.

This article about it might interest you : How to Use ignore_user_abort() to Do Processing Out of Band ; quoting :
EDIT 2010-03-22 : removed the link (was pointing to http:// ! waynepan.com/2007/10/11/ ! how-to-use-ignore_user_abort-to-do-process-out-of-band/ -- remove the spaces and ! if you want to try ), after seeing the comment of @Joel.

Basically, when you use ignore_user_abort(true) in your php script, the script will continue running even if the user pressed the esc or stop on his browser. How do you use this?
One use would be to return content to the user and allow the connection to be closed while processing things that don’t require user interaction.

The following example sends out $response to the user, closing the connection (making the browser’s spinner/loading bar stop), and then executes do_function_that_takes_five_mins();

And the given example :

ignore_user_abort(true);
header("Connection: close");
header("Content-Length: " . mb_strlen($response));
echo $response;
flush();
do_function_that_takes_five_mins();

(There's more I didn't copy-paste)


Note that your PHP script still has to fit in the max_execution_time and memory_limit constraints -- which means you shouldn't use this for manipulations that take too much time.

This will also use one Apache process -- which means you should not have dozens of pages that do that at the same time.

Still, nice trick to enhance use experience, I suppose ;-)

Pascal MARTIN
It's not working.You can try this to see it:ignore_user_abort(true);header('Content-Type:text/plain');header("Connection: close");echo 'something';sleep(20);exit();It still takes 20 seconds to respond.
Mask
The link to "How to Use ignore_user_abort() to Do Processing Out of Band" contains malware (when viewed via a referrer, suck as SO). Looks like the blog owner was hacked...
Joel L
@Joel : thanks for the comment ; I've edited my answer to remove the link ;; I've just left the URL, without an hyperlink, and with a warning
Pascal MARTIN
A: 

Mask - you need the flush() call to have the response sent to the browser immediately.

Joe