Reputation: 7725
I have an AJAX script that takes about 10 minutes to do its thing. I would like to be able to tell the user 'Hey listen, the task is being completed, we'll let you know how it turns out', but it won't let the user run any other scripts on the server until that one completes (I believe this is a consequence of PHP being single threaded, but I'm not sure). Is there a way to assign that AJAX script to a separate PHP or Apache process, so that the user can continue to click around in the application without having to wait for the task to finish?
Upvotes: 1
Views: 2154
Reputation: 339
Are you using PHP sessions? If so, then a likely cause is that the long-running script keeps the session locked until it finishes. Any other request trying to access that same session will have to wait until the first one is done (usually it'll exceed request timeouts).
To fix that you'll need session_write_close():
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
So simply call that function right around where you tell the user hey ya gotta wait
. If you need (read) access to session variables later on in that script, consider storing them in local variables, then close the session immediately afterwards before moving on to whatever's taking a long time. If you need write access you could try re-running session_start()
at the end, but if the session is currently locked elsewhere it'll have the same blocking problem. You could work around that by e.g. storing something in the database from the background script and fetching it from the regular user session, for example.
Upvotes: 0
Reputation: 2046
I seek for hours, at least, the solution was very easy for me using Cron Jobs. In cPanel you can go to Advanced -> Cron Jobs, and there schedule a task using a PHP script in Command line.
A Command example that execute a script php:
/usr/bin/wget http://www.example.com/miscript.php
or better:
php /home/USER/public_html/miscript.php
Upvotes: 0
Reputation: 10467
You can use database or files to insert some lock mechanism to prevent task from running multiple times simultaneously. Then you need to just spawn PHP process using command nohup
(no hang up), for more details look at this article: https://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/ or this question: nohup: run PHP process in background .
Upvotes: 3