I need to process a very long running process in PHP (grepping big text files and returning matching lines). When we run an average query from the command line, the process may take 10-15m.
I wanted to implement in PHP/jQuery, whereby I started the query, then showed incremental results as they came back.
I implemented something close, where I had one ajax call doing the search (worked fine), and had a periodic timer function running calling a second method in the class to get the results. However, I realized that the 2nd call would really create a new class instance, so the $this->current was different between the main query and the period update timer.
Here's the javascript I was trying (I was kicking it off when clicking a form button):
<script>
function update_status(data) {
alert(data);
jQuery.each(data, function(key, val) {
if ( key == "progress" )
$("#progressbar").progressbar({ value: val });
});
}
function progress_setup() {
setInterval(function() {
jQuery.ajax({
type:'POST',
dataType:'json',
complete:function(XMLHttpRequest, textStatus){
update_status(textStatus)
},
url:'<?php echo url_for("@grep_status"); ?>'
})},
2000);
}
function grep(elements) {
jQuery.ajax({
type:'POST',
dataType:'html',
data:jQuery(elements).serialize(),
success:function(data, textStatus){jQuery('#results').html(data);},
beforeSend:function(XMLHttpRequest){progress_setup()},
url:'/grep'});
}
</script>
But, this doesn't appear to be the right track. The core issue seems to be:
TIA Mike
You have to share the state of your operation either using a database or a file. Then in your /grep
operation you periodically write the state in the database or the file (updating the state).
Then you need another script (like /grep_state
) which reads the state and returns it to the client.
What you can't do is share the state using a PHP-object instance since this it's scope is limited to a single request. You have to persist the state.
The other Problem might be that your long running task is terminated because of a request timeout either by the webserver or the browser. I would either run the script in CLI-mode (detached from the webserver/request) or write a simple job-scheduler which runs as a daemon.
The daemon gets the parameters from a socket (or any other means of communicating with other processes) and starts the php-CLI with your worker-script. The state is also shared using files or a database.
Seems like the easiest thing to do is to split the task up in php and send some sort of flag back to your client side app to tell it when it's finished.
Maybe:
Although that wouldn't give you a perfect progress update, it would indicate how far you've searched into the file.
I think the key is to set up your server with parameters that allow you to limit/filter your query results.
You can try flushing your output early--this varies according to your server settings, however. For example:
// Script starts, does first block of program
echo "1";
flush();
// Second block starts and finishes
echo "2";
flush();
// Etc...
After each block completes, flush a response.