note 97713 deleted from function.proc-open by danbrown
| From: | danbrown@php.net | Date: | Tue, 04 May 2010 20:32:24 +0000 |
| Subject: | note 97713 deleted from function.proc-open by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-168937@lists.php.net to get a copy of this message | ||
Note Submitter: php at jeremygustafson dot net
----
I've added some features to the Processmanager class written by Matou Havlena. Adding a script
to the porocessmanager now supports an optional string of command line arguments. Also, return
values from child scripts are saved in an array, which is returned by the processmanager object.
Each element in the master array represents one child process, and each of those arrays is itself an
array of the stdout from the child, separated by line breaks.
<?php
class Processmanager {
public $executable = "/usr/bin/php";
public $root = "/path/to/web/root/"; // script paths are passed relative to this location
public $scripts = array();
public $processesRunning = 0;
public $processes = 30; // Max number of simultaneous processes
public $running = array();
public $sleep_time = 3; // Sleep time between checking for completed processes (and exec'ing
additional ones, if applicable)
public $arguments = ''; // Arguments passed to the script
public $return = array(); // return value to give to calling script; saves an array of all the
stdout from the child scripts
function addScript($script, $arguments = '', $max_execution_time = 300) {
$this->scripts[] = array("script_name" => $script,
"arguments" => $arguments,
"pipes" => array(), // to retrieve stdout from child scripts
"max_execution_time" => $max_execution_time);
}
function exec() {
$i = 0;
for(;;) {
// Fill up the slots
while (($this->processesRunning<$this->processes) and ($i<count($this->scripts))) {
echo "<span style='color: orange;'>Adding script:
".$this->scripts[$i]["script_name"]." with args
".$this->scripts[$i]["arguments"]."</span><br />";
ob_flush();
flush();
$this->running[] =& new Process($this->executable, $this->root,
$this->scripts[$i]["script_name"], $this->scripts[$i]["arguments"],
$this->scripts[$i]["pipes"], $this->scripts[$i]["max_execution_time"]);
$this->processesRunning++;
$i++;
}
// Check if done
if (($this->processesRunning==0) and ($i>=count($this->scripts))) {
break;
}
// sleep, this duration depends on your script execution time, the longer execution time, the
longer sleep time
sleep($this->sleep_time);
// check what is done
foreach ($this->running as $key => $val) {
if (!$val->isRunning() or $val->isOverExecuted()) {
if (!$val->isRunning()) echo "<span style='color: green;'>Done:
".$val->script." ".$val->arguments."</span><br />";
else echo "<span style='color: red;'>Killed: ".$val->script."
".$val->arguments."</span><br />";
$return[] = explode("\n",stream_get_contents($val->pipes[1]));
proc_close($val->resource);
unset($this->running[$key]);
$this->processesRunning--;
ob_flush();
flush();
}
}
}
return $return;
}
}
class Process {
public $resource;
public $pipes;
public $script;
public $max_execution_time;
public $start_time;
public $arguments;
function __construct(&$executable, &$root, $script, $arguments, $pipes,
$max_execution_time) {
$this->script = $script;
$this->arguments = $arguments;
$this->max_execution_time = $max_execution_time;
$this->pipes = $pipes;
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$this->resource = proc_open($executable." ".$root.$this->script."
".escapeshellarg($this->arguments), $descriptorspec, $this->pipes, null, $_ENV);
$this->start_time = mktime();
}
// is still running?
function isRunning() {
$status = proc_get_status($this->resource);
return $status["running"];
}
// long execution time, proccess is going to be killer
function isOverExecuted() {
if ($this->start_time+$this->max_execution_time<mktime()) return true;
else return false;
}
}
/*Example of using:
$manager = new Processmanager();
$manager->addScript("path/to/script1.php", "argument1 argument 2");
$manager->addScript("path/to/script2.php");
$manager->addScript("path/to/script1.php", "argument3");
$manager->exec();
*/
?>