Skip to content

Instantly share code, notes, and snippets.

@b00gizm
Created July 26, 2011 14:33
Show Gist options
  • Save b00gizm/1106905 to your computer and use it in GitHub Desktop.
Save b00gizm/1106905 to your computer and use it in GitHub Desktop.
Spawning node.js processes with PHP
<?php
class Foo
{
// ...
protected function spawnProcess()
{
if (!function_exists('proc_open')) {
throw new \RuntimeException(
'Unable to spawn a new process. (proc_open is not available on your PHP installation.)'
);
}
$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
$options = array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => true);
$this->process = proc_open(sprintf("node %s", $this->jsPath), $descriptors, $pipes, null, $options);
if (!is_resource($this->process)) {
throw new \RuntimeException('Unable to spawn a new process.');
}
foreach ($pipes as $pipe) {
stream_set_blocking($pipe, false);
}
// Constantly check the 'running' state of the process until it
// changes or drop out after a given amount of microseconds
$status = proc_get_status($this->process);
$time = 0;
while (1 == $status['running'] && $time < $this->threshold) {
$time += 1000;
usleep(1000);
$status = proc_get_status($this->process);
}
// If the process is not running, check STDERR for error messages
// and throw exception
if (0 == $status['running']) {
$err = stream_get_contents($pipes[2]);
$msg = 'Process is not running.';
if (!empty($err)) {
$msg .= sprintf(" (failed with error: %s", $err);
}
throw new \RuntimeException($msg);
}
// Close pipes to avoid deadlocks on proc_close
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
}
protected function killProcess()
{
if ($this->process) {
$status = proc_get_status($this->process);
posix_kill($status['pid'], SIGKILL);
proc_close($this->process);
$this->process = null;
}
}
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment