So I've been developing PHP for a bit now and have been attempting to troubleshoot why exec with a redirection of standard IO is still hanging the main thread.
exec(escapeshellcmd("php ".getcwd()."/orderProcessing.php" . " " . $Prepared . " " . escapeshellarg(35). "> /dev/null 2>&1 &"));
The code provided is what I've been trialing with, and I can't seem to get it to not hang until the other script completes. The reason I am doing this is in this paticular case, processing an order can take upto 30 seconds, and I don't want the user on the frontend to wait for that.
Can I only spawn child processes with php-fpm?
Is there something I have misconfigured?
Am I just misunderstanding how child processes work?
Setup is: Centos 7 with Apache HTTPD and PHP 8.1.11
Any help appreciated!
CodePudding user response:
Yes, it is possible in PHP. With proc_open() function, you can send command without wait another process. With handle opened stream, you can catch process status and check it consistently. For example:
$max = 5;
$streams = [];
$command = 'php ' . __DIR__ . '/../../process runSomeProcessCommand';
while (true) {
echo 'Working :' . count($streams) . "\n";
for ($i = 0; $i < $max; $i ) {
if (!isset($streams[$i])) {
$descriptor = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w']
];
echo "proc opened $i \n";
$streams[$i]['proc'] = proc_open($command . ":$i", $descriptor, $pipes);
$streams[$i]['pipes'] = $pipes;
$streams[$i]['ttl'] = time();
usleep(200000);
} else {
$info = proc_get_status($streams[$i]['proc']);
if ($info['running'] === false) {
echo "Finished $i . TTL: (" . (time() - $streams[$i]['ttl']) . " sec.).Response: " . stream_get_contents($streams[$i]['pipes'][1]) . " \n";
fclose($streams[$i]['pipes'][1]);
if ($error = stream_get_contents($streams[$i]['pipes'][2])) {
echo "Error for $i. Error: $error " . PHP_EOL;
fclose($streams[$i]['pipes'][2]);
}
proc_close($streams[$i]['proc']);
unset($streams[$i]);
} else {
echo "Running process (PID {$info['pid']}) - $i: \n";
}
# $return_value = proc_close($streams[$i]);
}
}
sleep(3);
}
There are 5 threads in same time which are doesn't wait one another.