multiple stream select with proc_open receive responses from slow process

913 Views Asked by At

I'm calling a slow python script as the child process (echonest remix code) from a WP plugin using proc_open and a variation on some code found here at this question.

The (python) script takes about a minute to process (a bunch of audio), and I'm hoping to find a way to display the output to the browser as it is printed from the python script. As it stands, the output of my entire function does not display until the proc_open and stream_select processes end. This even includes an echo statement at the start of the function.

<?php
echo "Why wait before printing me out?";

$description = array (     
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr
);

$application_system = "python ";
$application_name .= "glitcher/glitchmix.py";
$application = $application_system.$application_name.$separator;

$argv1 = 'a variable';
$argv2 = 'another variable';
$separator = " ";

$pipes = array();

$proc = proc_open ( $application.$separator.$argv1.$separator.$argv2, $description , $pipes, glitch_player_DIR);

// set all streams to non blockin mode
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);

// get PID via get_status call
$status = proc_get_status($proc);
// status check here if($status === FALSE)

$pid = $status['pid'];
// now, poll for childs termination
while(true) {
    // detect if the child has terminated - the php way
    $status = proc_get_status($proc);
    //  retval checks : ($status === FALSE) and ($status['running'] === FALSE)

    // read from childs stdout and stderr
    // avoid *forever* blocking through using a time out (1sec)
    foreach(array(1, 2) as $desc) {
        // check stdout for data
        $read = array($pipes[$desc]);
        $write = NULL;
        $except = NULL;
        $tv = 1;
        $n = stream_select($read, $write, $except, $tv);
        if($n > 0) {
            do {
                $data = fgets($pipes[$desc], 8092);
                echo $data . "\n<br/>";
            } while (strlen($data) > 0);
        }
    }
}
?>

Is it possible to use multiple calls to stream_select to echo the child process output as it comes?

Obviously I'm new to socket programming and look forward to some more insight from the S.O. community.

1

There are 1 best solutions below

2
On

It's funny and simple reason. See -u option for Python. I waste 2 days on same one problem. When I substitute python with bash and test some output from bash script - it immediately receive it.