1

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.

Community
  • 1
  • 1
MikeiLL
  • 6,282
  • 5
  • 37
  • 68
  • possibly `stream_copy_to_stream` or `stream_get_contents` can help. have experimented with `fgets` and `fread` as well, all of which have the same or nearly the same result so far. – MikeiLL May 30 '14 at 01:57
  • Got some GREAT feedback from the php general mailing list. Ran the php script from the command line and lo and behold, the python output is delivered as it comes from python. So it has to do with how php output is delivered to the browser. [this SO article] (http://stackoverflow.com/questions/4809774/transfer-encoding-chunked-header-in-php) was referred to me... – MikeiLL Jun 05 '14 at 23:51

1 Answers1

0

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.

HaveNoDisplayName
  • 8,291
  • 106
  • 37
  • 47
  • The issue is that I was using a python library for the subprocess so bash not an option as far as I can see. – MikeiLL Jul 14 '15 at 18:14
  • I only use bash for investigation. For python try use -u option in Your case. As `$application_system = "python -u ";` – Anton Gusev Jul 15 '15 at 06:41