Christoph
Christoph

Reputation: 41

php monitor process

I'm sure similar questions have bee answered over and over again. If yes then I googled in the wrong direction and apologize for that.

My problem: I'm writing a web page with a process running in the background. The process I'm talking about is a R script which runs quite long maybe several days. When the progress is started, its started like that.

exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));

Id' like to track whether the process is still running. This way, when the user checks he gets either the message that it is finished or not. The tracking starts and stops when the user chooses the input file he uploaded on to the server after for example he logs in again or did something else on the page. I also want it to update the page when the process finishes so the page changes in case he is just looking at it.

I have two possibilities. I can either check it via the process id or whether an output file is generated or not.

I tried

while(is_process_running($ps)){ ob_flush(); flush(); sleep(1); }

this works kind of, except that all other functionality on the page freezes. That's my is_process_running($ps) function.

function is_process_running($PID){ exec("ps $PID", $ProcessState); return(count($ProcessState) >= 2); }

What I really need is another process running in the background checking whether the first process is still running and if not, refreshes the page when the first process finishes. How would you do that? Please let me know if you need additional information. All help is much appreciated.

Upvotes: 1

Views: 459

Answers (2)

Christoph
Christoph

Reputation: 41

with symcbean's answer I was able to solve it. My javascript code is below maybe its of use to someone who faces the same problem. I'm also open for improvement. I still consider myself a beginner.

function loadXMLDoc(){
    var xmlhttp;
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }else{// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlhttp;
}
function start(file,time){
    var xmlhttp = loadXMLDoc();
    if(lines == 0){
        timer = setInterval(function(){sendRequest(xmlhttp,file)},time);
    }
}
function sendRequest(xmlhttp,file){
    xmlhttp.open("POST",file,true);
    xmlhttp.send()
    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200 && xmlhttp.responseText != ""){
            var text = xmlhttp.responseText;
            var splitted = text.split("\n");
            var length = splitted.length
            if(splitted[length-2]=="finished"){
                refresh_page();
                clearInterval(timer);
                lines = 0;
            }                   
        }
    }
}

The start method is called with file path and the time interval its supposed to check for changes. Note the refresh page method I did not post but that just whatever you want to refresh on your page. The page is refreshed when the last line in the file says finished. I included the line variable to check whether the process is already started or not. I have not fully tested the code but so far its doing what I want it to do.

Upvotes: 1

symcbean
symcbean

Reputation: 48357

First off, there are a number of issues with the way you are starting the process - it really needs to be a in a separate process group from the PHP which launches it.

As to checking its status, again, you don't want PHP stuff hanging around for a long time at the end of an http connection. Also getting the webserver to flush content to the browser on demand AND getting the browser to render it progressively is very difficult - and fragile. Even if you get it working on one browser/webserver combination it's unlikely to work in another.

Use Ajax to poll a simple script which reports back on the process status / progress.

Upvotes: 0

Related Questions