com phpruntests: phpruntests - update taskScheduler (prototype) - added file-driven ipc: code-samples/taskScheduler/classes/taskScheduler.php
code-samples/taskScheduler/classes/taskSchedulerFile.php code-samples/taskScheduler/classes/taskSchedulerMsgQ.php
code-samples/taskScheduler/results.xls code-samples/taskScheduler/run.php
| From: | David Soria Parra | Date: | Mon, 22 Jun 2009 00:19:12 +0000 |
| Subject: | com phpruntests: phpruntests - update taskScheduler (prototype) - added file-driven ipc: code-samples/taskScheduler/classes/taskScheduler.php code-samples/taskScheduler/classes/taskSchedulerFile.php code-samples/taskScheduler/classes/taskSchedulerMsgQ.php code-samples/taskScheduler/results.xls code-samples/taskScheduler/run.php |
||
| Groups: | php.qa | ||
| Request: | Send a blank email to php-qa+get-66407@lists.php.net to get a copy of this message | ||
Commit: b28bedb73555b7509001ec4cba2c72f6b56c9b1e
Author: Georg Gradwohl <g2@php.net> Mon, 22 Jun 2009 00:19:12 +0000
Parents: a69c8b431745c5c5ea32777d2751a562f1c7093d
Branches: master
Link: http://git.php.net/?p=phpruntests.git;a=commitdiff;h=b28bedb73555b7509001ec4cba2c72f6b56c9b1e
Log:
phpruntests - update taskScheduler (prototype) - added file-driven ipc
Changed paths:
M code-samples/taskScheduler/classes/taskScheduler.php
A code-samples/taskScheduler/classes/taskSchedulerFile.php
A code-samples/taskScheduler/classes/taskSchedulerMsgQ.php
A code-samples/taskScheduler/results.xls
M code-samples/taskScheduler/run.php
diff --git a/code-samples/taskScheduler/classes/taskScheduler.php b/code-samples/taskScheduler/classes/taskScheduler.php index 7452925..ed93e58 100644 --- a/code-samples/taskScheduler/classes/taskScheduler.php +++ b/code-samples/taskScheduler/classes/taskScheduler.php @@ -1,24 +1,17 @@ <?php -declare(ticks=true); - - class taskScheduler { - const MSG_QUEUE_KEY = 1234; // id of the message-queue - const MSG_QUEUE_SIZE = 1024; // max-size of a single message - const KILL_CHILD = 'killBill'; // kill-signal to terminate a child + protected $taskList = array(); // the list of the tasks to be executed + protected $processCount = 0; // the number of processes - private $taskList = array(); // the list of the tasks to be executed - private $processCount = NULL; // the number of processes - private $inputQueue = NULL; // the input-queue (only used by the sender) - private $pidStore = array(); // stores the pids of all child-processes - private $time = 0; // the needed time - private $countPass = 0; // counts the passed tasks - private $countFail = 0; // counts the failed tasks - private $groupTasks = false; // are the tasks stored in groups? - private $memStore = array(); // stores the mem-usage after an incomming task + protected $time = 0; // the needed time + protected $countPass = 0; // counts the passed tasks + protected $countFail = 0; // counts the failed tasks + protected $memStore = array(); // stores the mem-usage after an incomming task + + /** * the constructor @@ -34,24 +27,31 @@ class taskScheduler $this->setProcessCount($processCount); } + + + public static function getInstance(array $taskList=NULL, $processCount=NUL, $useMsgQ=false) + { + if (extension_loaded('pcntl')) { + + if ($useMsgQ === true) { + + return new taskSchedulerMsgQ($taskList, $processCount); + } + + return new taskSchedulerFile($taskList, $processCount); + } + + return new taskScheduler($taskList, $processCount); + } /** * sets the task-list which has to be an array of task-objects. - * it's also possible to use a multidimensional array. in this case the - * tasks are distributed to the child-processes exactly in the way as they - * are grouped in the list. the first-level index strictly has to be - * numeric and continuous starting with zero. - * + * * @param array $taskList */ public function setTaskList(array $taskList) { - if (is_array($taskList[0])) { - $this->groupTasks = true; - $this->processCount = sizeof($taskList); - } - $this->taskList = $taskList; } @@ -74,64 +74,18 @@ class taskScheduler */ public function setProcessCount($processCount) { - if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + if (is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** - * removes the used message-queues. - */ - private static function cleanUp() - { - @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); - @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); - logg("CLEAN UP"); - } - - - /** - * the signal-handler is called by the interrupt- or quit-signal and calls - * the cleanUp-method. - * - * @param int $signal - */ - public static function signalHandler($signal) - { - logg("SIGNAL: $signal"); - - switch($signal) { - - case SIGINT: - case SIGQUIT: - self::cleanUp(); - die("\n"); - break; - - default: - break; - } - } - - /** - * switch to run the classic- or the fork-mode - */ - public function run() - { - if ($this->processCount > 0) { - $this->runFork(); - } - else $this->runClassic(); - } - - - /** * executes the tasks in a simple loop * * @return void */ - private function runClassic() + public function run() { $s = microtime(true); @@ -147,6 +101,8 @@ class taskScheduler $this->countFail++; } + $this->memStore[] = memory_get_usage(true); + print "."; flush(); @@ -162,256 +118,6 @@ class taskScheduler /** - * starts the sender, the receiver and forks the defined - * number of child-processes. - * - * @return void - */ - private function runFork() - { - $startTime = microtime(true); - - // register signal-handler - pcntl_signal(SIGINT, "taskScheduler::signalHandler"); - pcntl_signal(SIGQUIT, "taskScheduler::signalHandler"); - - // trim the processCount if nesecarry - if (is_null($this->processCount) || $this->processCount > sizeof($this->taskList)) { - $this->processCount = sizeof($this->taskList); - } - - // fork the child-processes - for ($i=0; $i<=$this->processCount; $i++) { - - $this->pidStore[$i] = pcntl_fork(); - - switch ($this->pidStore[$i]) { - - case -1: // failure - die("could not fork"); - break; - - case 0: // child - if ($i==0) { - $this->sender(); - } else { - $cid = ($this->groupTasks == true) ? $i : NULL; - $this->child($cid); - } - break; - - default: // parent - break; - } - } - - // start the receiver - $this->receiver(); - - // wait until all child-processes are terminated - for ($i=0; $i<=$this->processCount; $i++) { - - pcntl_waitpid($this->pidStore[$i], $status); - logg("child $i terminated - status $status"); - } - - $endTime = microtime(true); - $this->time = round($endTime-$startTime,5); - - // remove the msg-queue - self::cleanUp(); - - logg("EXIT MAIN"); - return; - } - - - /** - * the receiver is listening to the result-queue and stores the incomming - * tasks back to the task-list. - * when finished it sends the kill-signal to all children and terminates - * itself. - * - * @return void - */ - private function receiver() - { - logg("RECEIVER START - ".sizeof($this->taskList)." tasks"); - - $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); - - $task = ''; - $type = 1; - - if ($this->groupTasks == true) { - $limit = 0; - foreach ($this->taskList as $list) { - $limit += sizeof($list); - } - } else { - $limit = sizeof($this->taskList); - } - - for ($i=0; $i<$limit; $i++) { - - $this->memStore[] = memory_get_usage(true); - - if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { - - // check state - if ($task->getState() == task::PASS) { - $this->countPass++; - } else { - $this->countFail++; - } - - // store result - $index = $task->getIndex(); - - if ($this->groupTasks == true) { - $this->taskList[$type-2][$index] = $task; - logg("RECEIVER store task ".($type-1)."-$index"); - - } else { - $this->taskList[$index] = $task; - logg("RECEIVER store task $index"); - } - - - } - else logg("RECEIVER ERROR $error"); - } - - $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - - for ($i=1; $i<=$this->processCount; $i++) { - - if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { - - logg("RECEIVER send KILL_CHILD"); - } - else logg("RECEIVER ERROR $error"); - } - - logg("RECEIVER EXIT"); - return; - } - - - /** - * the sender is passes through the task-list and distributes the single - * tasks to the child-processes using the input-queue. - * when finished it terminates itself. - * - * @return void - */ - private function sender() - { - logg("SENDER START - ".sizeof($this->taskList)." tasks"); - - $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - - for ($i=0; $i<sizeof($this->taskList); $i++) { - - if ($this->groupTasks == true) { - - for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { - - $this->sendTask($this->taskList[$i][$j], $j, $i+1); - } - - } else { - - $this->sendTask($this->taskList[$i], $i); - } - } - - logg("SENDER EXIT"); - exit(0); - } - - - /** - * helper-class of sender. - * sends a task to a child-process using the input-queue. - * - * @param task $task the task to send - * @param int $index the task's index in the taskList - * @param int $type the message-type (default=1) - * @return void - */ - private function sendTask(task $task, $index, $type=1) - { - $task->setIndex($index); - - if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { - - logg("SENDER send task $type - $index"); - } - else logg("SENDER ERROR $error"); - - return; - } - - - /** - * the child is listening to the input-queue and executes the incomming - * tasks. afterwards it setts the task-state and sends it back to the - * receiver via the result-queue. - * after receiving the kill-signal from the receiver it terminates itself. - * - * @param int $cid the child-id (default=NULL) - * @return void - */ - private function child($cid=NULL) - { - if (is_null($cid)) { - $cid = 0; - } - - logg("child $cid START"); - - $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); - - $type = 1; - - while (true) { - - if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { - - if ($task == self::KILL_CHILD) - break; - - $index = $task->getIndex(); - - logg("child $cid - run task $index"); - - if ($task->run() === true) { - $task->setState(task::PASS); - } else { - $task->setState(task::FAIL); - } - - print "."; - flush(); - - if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { - - logg("child $cid - send task $index"); - } - else logg("child $cid ERROR $error"); - - } - else logg("child $cid ERROR $error"); - } - - logg("child $cid EXIT"); - exit(0); - } - - - /** * prints the statistic * * @return void @@ -420,7 +126,7 @@ class taskScheduler { print "\n----------------------------------------\n"; - if ($this->groupTasks == true) { + if (is_array($this->taskList[0])) { $count = 0; foreach ($this->taskList as $list) { diff --git a/code-samples/taskScheduler/classes/taskSchedulerFile.php b/code-samples/taskScheduler/classes/taskSchedulerFile.php new file mode 100644 index 0000000..73214fa --- /dev/null +++ b/code-samples/taskScheduler/classes/taskSchedulerFile.php @@ -0,0 +1,301 @@ +<?php + +class taskSchedulerFile extends taskScheduler +{ + const TMP_FILE = 'taskFile'; + + private $inputQueue = NULL; // the input-queue (only used by the sender) + private $pidStore = array(); // stores the pids of all child-processes + private $groupTasks = false; // are the tasks stored in groups? + + private $tmpTaskList = array(); + + /** + * the constructor + * + * @param array $taskList (optional) + * @param int $processCount (optional) + */ + public function __construct(array $taskList=NULL, $processCount=NULL) + { + if (is_array($taskList)) { + $this->setTaskList($taskList); + } + + $this->setProcessCount($processCount); + } + + + /** + * sets the task-list which has to be an array of task-objects. + * it's also possible to use a multidimensional array. in this case the + * tasks are distributed to the child-processes exactly in the way as they + * are grouped in the list. the first-level index strictly has to be + * numeric and continuous starting with zero. + * + * @param array $taskList + * @Overrides + */ + public function setTaskList(array $taskList) + { + if (is_array($taskList[0])) { + $this->groupTasks = true; + $this->processCount = sizeof($taskList); + } + + $this->taskList = $taskList; + } + + + + /** + * sets the number of child-processes. + * in the case of using a multidimensional task-list this parameter is + * ignored and set to the number of task-groups. + * + * @param int $count + * @Overrides + */ + public function setProcessCount($processCount) + { + if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + $this->processCount = $processCount; + } + } + + + + /** + * starts the sender, the receiver and forks the defined + * number of child-processes. + * + * @return void + * @Overrides + */ + public function run() + { + if ($this->processCount == 0) { + return parent::run(); + } + + $startTime = microtime(true); + + // trim the processCount if nesecarry + if ($this->processCount > sizeof($this->taskList)) { + $this->processCount = sizeof($this->taskList); + } + + $this->createTaskFiles(); + + + // fork the child-processes + for ($i=1; $i<=$this->processCount; $i++) { + + $this->pidStore[$i] = pcntl_fork(); + + switch ($this->pidStore[$i]) { + + case -1: // failure + die("could not fork"); + break; + + case 0: // child + $this->child($i-1); + break; + + default: // parent + break; + } + } + + // wait until all child-processes are terminated + for ($i=0; $i<$this->processCount; $i++) { + + pcntl_waitpid($this->pidStore[$i], $status); + logg("child $i terminated - status $status"); + } + + // ensure that the tmp-files are completly written + sleep(1); + + // collecting the results + $this->receiver($i); + + $endTime = microtime(true); + $this->time = round($endTime-$startTime,5); + + logg("EXIT MAIN"); + return; + } + + + + /** + * creates a temporary file for each child which stores the allocated + * array-indices. + * + */ + private function createTaskFiles() { + + $taskStr = array(); + + if ($this->groupTasks == true) { + + $c = 0; + + foreach ($this->taskList as $key => $list) { + + for ($i=0; $i<sizeof($list); $i++) { + + $taskStr[$key] .= $i.';'; + } + } + + } else { + + for ($i=0; $i<sizeof($this->taskList); $i++) { + + $taskStr[$i%$this->processCount] .= $i.';'; + } + } + + for ($i=0; $i<$this->processCount; $i++) { + + file_put_contents(self::TMP_FILE.$i, $taskStr[$i]); + } + } + + + + /** + * @return void + */ + private function receiver() + { + logg("RECEIVER START"); + + for ($cid=0; $cid<$this->processCount; $cid++) { + + $response = file_get_contents(self::TMP_FILE.$cid); + $response = explode("\n", $response); + array_pop($response); + + foreach ($response as $task) { + + $task = unserialize($task); + + if ($task->getState() == task::PASS) { + $this->countPass++; + } else { + $this->countFail++; + } + + $index = $task->getIndex(); + + if ($this->groupTasks == true) { + + $this->taskList[$cid][$index] = $task; + + } else { + + $this->taskList[$index] = $task; + } + } + + unlink(self::TMP_FILE.$cid); + } + + return; + } + + + + /** + * @param int $cid the child-id + * @return void + */ + private function child($cid) + { + logg("child $cid START"); + + $indexList = file_get_contents(self::TMP_FILE.$cid); + $indexList = explode(';', $indexList); + array_pop($indexList); + + $response = ''; + + foreach ($indexList as $index) { + + logg("child $cid - run task $index"); + + if ($this->groupTasks == true) { + $task = $this->taskList[$cid][$index]; + } else { + $task = $this->taskList[$index]; + } + + if ($task->run() === true) { + $task->setState(task::PASS); + + } else { + $task->setState(task::FAIL); + } + + $task->setIndex($index); + + print "."; + flush(); + + $response .= serialize($task)."\n"; + } + + file_put_contents(self::TMP_FILE.$cid, $response, LOCK_EX); + + logg("child $cid EXIT"); + exit(0); + } + + + /** + * prints the statistic + * + * @return void + */ + public function printStatistic() + { + print "\n----------------------------------------\n"; + + if (is_array($this->taskList[0])) { + + $count = 0; + foreach ($this->taskList as $list) { + $count += sizeof($list); + } + + print "Groups:\t\t".sizeof($this->taskList)."\n"; + print "Tasks:\t\t".$count."\n"; + + } else { + + $count = sizeof($this->taskList); + print "Tasks:\t\t".$count."\n"; + } + + print "PASSED:\t\t".$this->countPass." (".round($this->countPass/$count*100,2)."%)\n"; + print "FAILED:\t\t".$this->countFail." (".round($this->countFail/$count*100,2)."%)\n"; + print "Processes:\t".$this->processCount."\n"; + print "Seconds:\t".$this->time."\n"; + + + print "----------------------------------------\n"; + flush(); + } + + + public function printMemStatistic($int=10) {} + + + +} + +?> \ No newline at end of file diff --git a/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php b/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php new file mode 100644 index 0000000..eca4f70 --- /dev/null +++ b/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php @@ -0,0 +1,352 @@ +<?php + +declare(ticks=true); + + +class taskSchedulerMsgQ extends taskScheduler +{ + const MSG_QUEUE_KEY = 1234; // id of the message-queue + const MSG_QUEUE_SIZE = 1024; // max-size of a single message + const KILL_CHILD = 'killBill'; // kill-signal to terminate a child + + private $inputQueue = NULL; // the input-queue (only used by the sender) + private $pidStore = array(); // stores the pids of all child-processes + private $groupTasks = false; // are the tasks stored in groups? + + + + + + /** + * sets the task-list which has to be an array of task-objects. + * it's also possible to use a multidimensional array. in this case the + * tasks are distributed to the child-processes exactly in the way as they + * are grouped in the list. the first-level index strictly has to be + * numeric and continuous starting with zero. + * + * @param array $taskList + * @Overrides + */ + public function setTaskList(array $taskList) + { + if (is_array($taskList[0])) { + $this->groupTasks = true; + $this->processCount = sizeof($taskList); + } + + $this->taskList = $taskList; + } + + + + /** + * sets the number of child-processes. + * in the case of using a multidimensional task-list this parameter is + * ignored and set to the number of task-groups. + * + * @param int $count + * @Overrides + */ + public function setProcessCount($processCount) + { + if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + $this->processCount = $processCount; + } + } + + + /** + * removes the used message-queues. + */ + private static function cleanUp() + { + @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); + @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); + logg("CLEAN UP"); + } + + + /** + * the signal-handler is called by the interrupt- or quit-signal and calls + * the cleanUp-method. + * + * @param int $signal + */ + public static function signalHandler($signal) + { + logg("SIGNAL: $signal"); + + switch($signal) { + + case SIGINT: + case SIGQUIT: + self::cleanUp(); + die("\n"); + break; + + default: + break; + } + } + + + /** + * starts the sender, the receiver and forks the defined + * number of child-processes. + * + * @return void + * @Overrides + */ + public function run() + { + + if ($this->processCount == 0) { + return parent::run(); + } + + + $startTime = microtime(true); + + // register signal-handler + pcntl_signal(SIGINT, "taskSchedulerMsgQ::signalHandler"); + pcntl_signal(SIGQUIT, "taskSchedulerMsgQ::signalHandler"); + + // trim the processCount if nesecarry + if ($this->processCount > sizeof($this->taskList)) { + $this->processCount = sizeof($this->taskList); + } + + // fork the child-processes + for ($i=0; $i<=$this->processCount; $i++) { + + $this->pidStore[$i] = pcntl_fork(); + + switch ($this->pidStore[$i]) { + + case -1: // failure + die("could not fork"); + break; + + case 0: // child + if ($i==0) { + $this->sender(); + } else { + $cid = ($this->groupTasks == true) ? $i : NULL; + $this->child($cid); + } + break; + + default: // parent + break; + } + } + + // start the receiver + $this->receiver(); + + // wait until all child-processes are terminated + for ($i=0; $i<=$this->processCount; $i++) { + + pcntl_waitpid($this->pidStore[$i], $status); + logg("child $i terminated - status $status"); + } + + $endTime = microtime(true); + $this->time = round($endTime-$startTime,5); + + // remove the msg-queue + self::cleanUp(); + + logg("EXIT MAIN"); + return; + } + + + /** + * the receiver is listening to the result-queue and stores the incomming + * tasks back to the task-list. + * when finished it sends the kill-signal to all children and terminates + * itself. + * + * @return void + */ + private function receiver() + { + logg("RECEIVER START - ".sizeof($this->taskList)." tasks"); + + $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); + + $task = ''; + $type = 1; + + if ($this->groupTasks == true) { + $limit = 0; + foreach ($this->taskList as $list) { + $limit += sizeof($list); + } + } else { + $limit = sizeof($this->taskList); + } + + for ($i=0; $i<$limit; $i++) { + + $this->memStore[] = memory_get_usage(true); + + if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { + + // check state + if ($task->getState() == task::PASS) { + $this->countPass++; + } else { + $this->countFail++; + } + + // store result + $index = $task->getIndex(); + + if ($this->groupTasks == true) { + $this->taskList[$type-2][$index] = $task; + logg("RECEIVER store task ".($type-1)."-$index"); + + } else { + $this->taskList[$index] = $task; + logg("RECEIVER store task $index"); + } + + + } + else logg("RECEIVER ERROR $error"); + } + + $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); + + for ($i=1; $i<=$this->processCount; $i++) { + + if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { + + logg("RECEIVER send KILL_CHILD"); + } + else logg("RECEIVER ERROR $error"); + } + + logg("RECEIVER EXIT"); + return; + } + + + /** + * the sender is passes through the task-list and distributes the single + * tasks to the child-processes using the input-queue. + * when finished it terminates itself. + * + * @return void + */ + private function sender() + { + logg("SENDER START - ".sizeof($this->taskList)." tasks"); + + $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); + + for ($i=0; $i<sizeof($this->taskList); $i++) { + + if ($this->groupTasks == true) { + + for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { + + $this->sendTask($this->taskList[$i][$j], $j, $i+1); + } + + } else { + + $this->sendTask($this->taskList[$i], $i); + } + } + + logg("SENDER EXIT"); + exit(0); + } + + + /** + * helper-class of sender. + * sends a task to a child-process using the input-queue. + * + * @param task $task the task to send + * @param int $index the task's index in the taskList + * @param int $type the message-type (default=1) + * @return void + */ + private function sendTask(task $task, $index, $type=1) + { + $task->setIndex($index); + + if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { + + logg("SENDER send task $type - $index"); + } + else logg("SENDER ERROR $error"); + + return; + } + + + /** + * the child is listening to the input-queue and executes the incomming + * tasks. afterwards it setts the task-state and sends it back to the + * receiver via the result-queue. + * after receiving the kill-signal from the receiver it terminates itself. + * + * @param int $cid the child-id (default=NULL) + * @return void + */ + private function child($cid=NULL) + { + if (is_null($cid)) { + $cid = 0; + } + + logg("child $cid START"); + + $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); + $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); + + $type = 1; + + while (true) { + + if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { + + if ($task == self::KILL_CHILD) + break; + + $index = $task->getIndex(); + + logg("child $cid - run task $index"); + + if ($task->run() === true) { + $task->setState(task::PASS); + } else { + $task->setState(task::FAIL); + } + + print "."; + flush(); + + if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { + + logg("child $cid - send task $index"); + } + else logg("child $cid ERROR $error"); + + } + else logg("child $cid ERROR $error"); + } + + logg("child $cid EXIT"); + exit(0); + } + + +} + +?> \ No newline at end of file diff --git a/code-samples/taskScheduler/results.xls b/code-samples/taskScheduler/results.xls new file mode 100644 index 0000000..7bb59be Binary files /dev/null and b/code-samples/taskScheduler/results.xls differ diff --git a/code-samples/taskScheduler/run.php b/code-samples/taskScheduler/run.php index 29b8e17..51aef04 100644 --- a/code-samples/taskScheduler/run.php +++ b/code-samples/taskScheduler/run.php @@ -1,6 +1,8 @@ <?php include 'classes/taskScheduler.php'; +include 'classes/taskSchedulerMsgQ.php'; +include 'classes/taskSchedulerFile.php'; include 'classes/taskInterface.php'; include 'classes/task.php'; @@ -25,14 +27,15 @@ function logg($msg) { $argc = sizeof($argv); -if ($argc >= 2 || $argc <= 3) { +if ($argc >= 2 || $argc <= 4) { $src = $argv[1]; $count = isset($argv[2]) ? $argv[2] : NULL; + $useMsgQ = isset($argv[3]); } else { - die("USAGE: php run.php example processCount\n"); + die("USAGE: php run.php example processCount useMsgQ\n"); } @@ -50,20 +53,21 @@ include $src; $taskList = createTaskList($count); + // init scheduler -$c = new taskScheduler(); +$c = taskScheduler::getInstance($taskList, $count, $useMsgQ); + $c->setTaskList($taskList); $c->setProcessCount($count); $c->run(); -$c->printStatistic(); - -// var_dump($c->getTaskList()); +$c->printStatistic(); $c->printFailedTasks(); - $c->printMemStatistic(10); +// var_dump($c->getTaskList()); + exit(0); ?>
diff --git a/code-samples/taskScheduler/classes/taskScheduler.php b/code-samples/taskScheduler/classes/taskScheduler.php index 7452925..ed93e58 100644 --- a/code-samples/taskScheduler/classes/taskScheduler.php +++ b/code-samples/taskScheduler/classes/taskScheduler.php @@ -1,24 +1,17 @@ <?php -declare(ticks=true); - - class taskScheduler { - const MSG_QUEUE_KEY = 1234; // id of the message-queue - const MSG_QUEUE_SIZE = 1024; // max-size of a single message - const KILL_CHILD = 'killBill'; // kill-signal to terminate a child + protected $taskList = array(); // the list of the tasks to be executed + protected $processCount = 0; // the number of processes - private $taskList = array(); // the list of the tasks to be executed - private $processCount = NULL; // the number of processes - private $inputQueue = NULL; // the input-queue (only used by the sender) - private $pidStore = array(); // stores the pids of all child-processes - private $time = 0; // the needed time - private $countPass = 0; // counts the passed tasks - private $countFail = 0; // counts the failed tasks - private $groupTasks = false; // are the tasks stored in groups? - private $memStore = array(); // stores the mem-usage after an incomming task + protected $time = 0; // the needed time + protected $countPass = 0; // counts the passed tasks + protected $countFail = 0; // counts the failed tasks + protected $memStore = array(); // stores the mem-usage after an incomming task + + /** * the constructor @@ -34,24 +27,31 @@ class taskScheduler $this->setProcessCount($processCount); } + + + public static function getInstance(array $taskList=NULL, $processCount=NUL, $useMsgQ=false) + { + if (extension_loaded('pcntl')) { + + if ($useMsgQ === true) { + + return new taskSchedulerMsgQ($taskList, $processCount); + } + + return new taskSchedulerFile($taskList, $processCount); + } + + return new taskScheduler($taskList, $processCount); + } /** * sets the task-list which has to be an array of task-objects. - * it's also possible to use a multidimensional array. in this case the - * tasks are distributed to the child-processes exactly in the way as they - * are grouped in the list. the first-level index strictly has to be - * numeric and continuous starting with zero. - * + * * @param array $taskList */ public function setTaskList(array $taskList) { - if (is_array($taskList[0])) { - $this->groupTasks = true; - $this->processCount = sizeof($taskList); - } - $this->taskList = $taskList; } @@ -74,64 +74,18 @@ class taskScheduler */ public function setProcessCount($processCount) { - if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + if (is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** - * removes the used message-queues. - */ - private static function cleanUp() - { - @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); - @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); - logg("CLEAN UP"); - } - - - /** - * the signal-handler is called by the interrupt- or quit-signal and calls - * the cleanUp-method. - * - * @param int $signal - */ - public static function signalHandler($signal) - { - logg("SIGNAL: $signal"); - - switch($signal) { - - case SIGINT: - case SIGQUIT: - self::cleanUp(); - die("\n"); - break; - - default: - break; - } - } - - /** - * switch to run the classic- or the fork-mode - */ - public function run() - { - if ($this->processCount > 0) { - $this->runFork(); - } - else $this->runClassic(); - } - - - /** * executes the tasks in a simple loop * * @return void */ - private function runClassic() + public function run() { $s = microtime(true); @@ -147,6 +101,8 @@ class taskScheduler $this->countFail++; } + $this->memStore[] = memory_get_usage(true); + print "."; flush(); @@ -162,256 +118,6 @@ class taskScheduler /** - * starts the sender, the receiver and forks the defined - * number of child-processes. - * - * @return void - */ - private function runFork() - { - $startTime = microtime(true); - - // register signal-handler - pcntl_signal(SIGINT, "taskScheduler::signalHandler"); - pcntl_signal(SIGQUIT, "taskScheduler::signalHandler"); - - // trim the processCount if nesecarry - if (is_null($this->processCount) || $this->processCount > sizeof($this->taskList)) { - $this->processCount = sizeof($this->taskList); - } - - // fork the child-processes - for ($i=0; $i<=$this->processCount; $i++) { - - $this->pidStore[$i] = pcntl_fork(); - - switch ($this->pidStore[$i]) { - - case -1: // failure - die("could not fork"); - break; - - case 0: // child - if ($i==0) { - $this->sender(); - } else { - $cid = ($this->groupTasks == true) ? $i : NULL; - $this->child($cid); - } - break; - - default: // parent - break; - } - } - - // start the receiver - $this->receiver(); - - // wait until all child-processes are terminated - for ($i=0; $i<=$this->processCount; $i++) { - - pcntl_waitpid($this->pidStore[$i], $status); - logg("child $i terminated - status $status"); - } - - $endTime = microtime(true); - $this->time = round($endTime-$startTime,5); - - // remove the msg-queue - self::cleanUp(); - - logg("EXIT MAIN"); - return; - } - - - /** - * the receiver is listening to the result-queue and stores the incomming - * tasks back to the task-list. - * when finished it sends the kill-signal to all children and terminates - * itself. - * - * @return void - */ - private function receiver() - { - logg("RECEIVER START - ".sizeof($this->taskList)." tasks"); - - $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); - - $task = ''; - $type = 1; - - if ($this->groupTasks == true) { - $limit = 0; - foreach ($this->taskList as $list) { - $limit += sizeof($list); - } - } else { - $limit = sizeof($this->taskList); - } - - for ($i=0; $i<$limit; $i++) { - - $this->memStore[] = memory_get_usage(true); - - if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { - - // check state - if ($task->getState() == task::PASS) { - $this->countPass++; - } else { - $this->countFail++; - } - - // store result - $index = $task->getIndex(); - - if ($this->groupTasks == true) { - $this->taskList[$type-2][$index] = $task; - logg("RECEIVER store task ".($type-1)."-$index"); - - } else { - $this->taskList[$index] = $task; - logg("RECEIVER store task $index"); - } - - - } - else logg("RECEIVER ERROR $error"); - } - - $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - - for ($i=1; $i<=$this->processCount; $i++) { - - if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { - - logg("RECEIVER send KILL_CHILD"); - } - else logg("RECEIVER ERROR $error"); - } - - logg("RECEIVER EXIT"); - return; - } - - - /** - * the sender is passes through the task-list and distributes the single - * tasks to the child-processes using the input-queue. - * when finished it terminates itself. - * - * @return void - */ - private function sender() - { - logg("SENDER START - ".sizeof($this->taskList)." tasks"); - - $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - - for ($i=0; $i<sizeof($this->taskList); $i++) { - - if ($this->groupTasks == true) { - - for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { - - $this->sendTask($this->taskList[$i][$j], $j, $i+1); - } - - } else { - - $this->sendTask($this->taskList[$i], $i); - } - } - - logg("SENDER EXIT"); - exit(0); - } - - - /** - * helper-class of sender. - * sends a task to a child-process using the input-queue. - * - * @param task $task the task to send - * @param int $index the task's index in the taskList - * @param int $type the message-type (default=1) - * @return void - */ - private function sendTask(task $task, $index, $type=1) - { - $task->setIndex($index); - - if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { - - logg("SENDER send task $type - $index"); - } - else logg("SENDER ERROR $error"); - - return; - } - - - /** - * the child is listening to the input-queue and executes the incomming - * tasks. afterwards it setts the task-state and sends it back to the - * receiver via the result-queue. - * after receiving the kill-signal from the receiver it terminates itself. - * - * @param int $cid the child-id (default=NULL) - * @return void - */ - private function child($cid=NULL) - { - if (is_null($cid)) { - $cid = 0; - } - - logg("child $cid START"); - - $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); - - $type = 1; - - while (true) { - - if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { - - if ($task == self::KILL_CHILD) - break; - - $index = $task->getIndex(); - - logg("child $cid - run task $index"); - - if ($task->run() === true) { - $task->setState(task::PASS); - } else { - $task->setState(task::FAIL); - } - - print "."; - flush(); - - if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { - - logg("child $cid - send task $index"); - } - else logg("child $cid ERROR $error"); - - } - else logg("child $cid ERROR $error"); - } - - logg("child $cid EXIT"); - exit(0); - } - - - /** * prints the statistic * * @return void @@ -420,7 +126,7 @@ class taskScheduler { print "\n----------------------------------------\n"; - if ($this->groupTasks == true) { + if (is_array($this->taskList[0])) { $count = 0; foreach ($this->taskList as $list) { diff --git a/code-samples/taskScheduler/classes/taskSchedulerFile.php b/code-samples/taskScheduler/classes/taskSchedulerFile.php new file mode 100644 index 0000000..73214fa --- /dev/null +++ b/code-samples/taskScheduler/classes/taskSchedulerFile.php @@ -0,0 +1,301 @@ +<?php + +class taskSchedulerFile extends taskScheduler +{ + const TMP_FILE = 'taskFile'; + + private $inputQueue = NULL; // the input-queue (only used by the sender) + private $pidStore = array(); // stores the pids of all child-processes + private $groupTasks = false; // are the tasks stored in groups? + + private $tmpTaskList = array(); + + /** + * the constructor + * + * @param array $taskList (optional) + * @param int $processCount (optional) + */ + public function __construct(array $taskList=NULL, $processCount=NULL) + { + if (is_array($taskList)) { + $this->setTaskList($taskList); + } + + $this->setProcessCount($processCount); + } + + + /** + * sets the task-list which has to be an array of task-objects. + * it's also possible to use a multidimensional array. in this case the + * tasks are distributed to the child-processes exactly in the way as they + * are grouped in the list. the first-level index strictly has to be + * numeric and continuous starting with zero. + * + * @param array $taskList + * @Overrides + */ + public function setTaskList(array $taskList) + { + if (is_array($taskList[0])) { + $this->groupTasks = true; + $this->processCount = sizeof($taskList); + } + + $this->taskList = $taskList; + } + + + + /** + * sets the number of child-processes. + * in the case of using a multidimensional task-list this parameter is + * ignored and set to the number of task-groups. + * + * @param int $count + * @Overrides + */ + public function setProcessCount($processCount) + { + if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + $this->processCount = $processCount; + } + } + + + + /** + * starts the sender, the receiver and forks the defined + * number of child-processes. + * + * @return void + * @Overrides + */ + public function run() + { + if ($this->processCount == 0) { + return parent::run(); + } + + $startTime = microtime(true); + + // trim the processCount if nesecarry + if ($this->processCount > sizeof($this->taskList)) { + $this->processCount = sizeof($this->taskList); + } + + $this->createTaskFiles(); + + + // fork the child-processes + for ($i=1; $i<=$this->processCount; $i++) { + + $this->pidStore[$i] = pcntl_fork(); + + switch ($this->pidStore[$i]) { + + case -1: // failure + die("could not fork"); + break; + + case 0: // child + $this->child($i-1); + break; + + default: // parent + break; + } + } + + // wait until all child-processes are terminated + for ($i=0; $i<$this->processCount; $i++) { + + pcntl_waitpid($this->pidStore[$i], $status); + logg("child $i terminated - status $status"); + } + + // ensure that the tmp-files are completly written + sleep(1); + + // collecting the results + $this->receiver($i); + + $endTime = microtime(true); + $this->time = round($endTime-$startTime,5); + + logg("EXIT MAIN"); + return; + } + + + + /** + * creates a temporary file for each child which stores the allocated + * array-indices. + * + */ + private function createTaskFiles() { + + $taskStr = array(); + + if ($this->groupTasks == true) { + + $c = 0; + + foreach ($this->taskList as $key => $list) { + + for ($i=0; $i<sizeof($list); $i++) { + + $taskStr[$key] .= $i.';'; + } + } + + } else { + + for ($i=0; $i<sizeof($this->taskList); $i++) { + + $taskStr[$i%$this->processCount] .= $i.';'; + } + } + + for ($i=0; $i<$this->processCount; $i++) { + + file_put_contents(self::TMP_FILE.$i, $taskStr[$i]); + } + } + + + + /** + * @return void + */ + private function receiver() + { + logg("RECEIVER START"); + + for ($cid=0; $cid<$this->processCount; $cid++) { + + $response = file_get_contents(self::TMP_FILE.$cid); + $response = explode("\n", $response); + array_pop($response); + + foreach ($response as $task) { + + $task = unserialize($task); + + if ($task->getState() == task::PASS) { + $this->countPass++; + } else { + $this->countFail++; + } + + $index = $task->getIndex(); + + if ($this->groupTasks == true) { + + $this->taskList[$cid][$index] = $task; + + } else { + + $this->taskList[$index] = $task; + } + } + + unlink(self::TMP_FILE.$cid); + } + + return; + } + + + + /** + * @param int $cid the child-id + * @return void + */ + private function child($cid) + { + logg("child $cid START"); + + $indexList = file_get_contents(self::TMP_FILE.$cid); + $indexList = explode(';', $indexList); + array_pop($indexList); + + $response = ''; + + foreach ($indexList as $index) { + + logg("child $cid - run task $index"); + + if ($this->groupTasks == true) { + $task = $this->taskList[$cid][$index]; + } else { + $task = $this->taskList[$index]; + } + + if ($task->run() === true) { + $task->setState(task::PASS); + + } else { + $task->setState(task::FAIL); + } + + $task->setIndex($index); + + print "."; + flush(); + + $response .= serialize($task)."\n"; + } + + file_put_contents(self::TMP_FILE.$cid, $response, LOCK_EX); + + logg("child $cid EXIT"); + exit(0); + } + + + /** + * prints the statistic + * + * @return void + */ + public function printStatistic() + { + print "\n----------------------------------------\n"; + + if (is_array($this->taskList[0])) { + + $count = 0; + foreach ($this->taskList as $list) { + $count += sizeof($list); + } + + print "Groups:\t\t".sizeof($this->taskList)."\n"; + print "Tasks:\t\t".$count."\n"; + + } else { + + $count = sizeof($this->taskList); + print "Tasks:\t\t".$count."\n"; + } + + print "PASSED:\t\t".$this->countPass." (".round($this->countPass/$count*100,2)."%)\n"; + print "FAILED:\t\t".$this->countFail." (".round($this->countFail/$count*100,2)."%)\n"; + print "Processes:\t".$this->processCount."\n"; + print "Seconds:\t".$this->time."\n"; + + + print "----------------------------------------\n"; + flush(); + } + + + public function printMemStatistic($int=10) {} + + + +} + +?> \ No newline at end of file diff --git a/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php b/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php new file mode 100644 index 0000000..eca4f70 --- /dev/null +++ b/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php @@ -0,0 +1,352 @@ +<?php + +declare(ticks=true); + + +class taskSchedulerMsgQ extends taskScheduler +{ + const MSG_QUEUE_KEY = 1234; // id of the message-queue + const MSG_QUEUE_SIZE = 1024; // max-size of a single message + const KILL_CHILD = 'killBill'; // kill-signal to terminate a child + + private $inputQueue = NULL; // the input-queue (only used by the sender) + private $pidStore = array(); // stores the pids of all child-processes + private $groupTasks = false; // are the tasks stored in groups? + + + + + + /** + * sets the task-list which has to be an array of task-objects. + * it's also possible to use a multidimensional array. in this case the + * tasks are distributed to the child-processes exactly in the way as they + * are grouped in the list. the first-level index strictly has to be + * numeric and continuous starting with zero. + * + * @param array $taskList + * @Overrides + */ + public function setTaskList(array $taskList) + { + if (is_array($taskList[0])) { + $this->groupTasks = true; + $this->processCount = sizeof($taskList); + } + + $this->taskList = $taskList; + } + + + + /** + * sets the number of child-processes. + * in the case of using a multidimensional task-list this parameter is + * ignored and set to the number of task-groups. + * + * @param int $count + * @Overrides + */ + public function setProcessCount($processCount) + { + if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + $this->processCount = $processCount; + } + } + + + /** + * removes the used message-queues. + */ + private static function cleanUp() + { + @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); + @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); + logg("CLEAN UP"); + } + + + /** + * the signal-handler is called by the interrupt- or quit-signal and calls + * the cleanUp-method. + * + * @param int $signal + */ + public static function signalHandler($signal) + { + logg("SIGNAL: $signal"); + + switch($signal) { + + case SIGINT: + case SIGQUIT: + self::cleanUp(); + die("\n"); + break; + + default: + break; + } + } + + + /** + * starts the sender, the receiver and forks the defined + * number of child-processes. + * + * @return void + * @Overrides + */ + public function run() + { + + if ($this->processCount == 0) { + return parent::run(); + } + + + $startTime = microtime(true); + + // register signal-handler + pcntl_signal(SIGINT, "taskSchedulerMsgQ::signalHandler"); + pcntl_signal(SIGQUIT, "taskSchedulerMsgQ::signalHandler"); + + // trim the processCount if nesecarry + if ($this->processCount > sizeof($this->taskList)) { + $this->processCount = sizeof($this->taskList); + } + + // fork the child-processes + for ($i=0; $i<=$this->processCount; $i++) { + + $this->pidStore[$i] = pcntl_fork(); + + switch ($this->pidStore[$i]) { + + case -1: // failure + die("could not fork"); + break; + + case 0: // child + if ($i==0) { + $this->sender(); + } else { + $cid = ($this->groupTasks == true) ? $i : NULL; + $this->child($cid); + } + break; + + default: // parent + break; + } + } + + // start the receiver + $this->receiver(); + + // wait until all child-processes are terminated + for ($i=0; $i<=$this->processCount; $i++) { + + pcntl_waitpid($this->pidStore[$i], $status); + logg("child $i terminated - status $status"); + } + + $endTime = microtime(true); + $this->time = round($endTime-$startTime,5); + + // remove the msg-queue + self::cleanUp(); + + logg("EXIT MAIN"); + return; + } + + + /** + * the receiver is listening to the result-queue and stores the incomming + * tasks back to the task-list. + * when finished it sends the kill-signal to all children and terminates + * itself. + * + * @return void + */ + private function receiver() + { + logg("RECEIVER START - ".sizeof($this->taskList)." tasks"); + + $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); + + $task = ''; + $type = 1; + + if ($this->groupTasks == true) { + $limit = 0; + foreach ($this->taskList as $list) { + $limit += sizeof($list); + } + } else { + $limit = sizeof($this->taskList); + } + + for ($i=0; $i<$limit; $i++) { + + $this->memStore[] = memory_get_usage(true); + + if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { + + // check state + if ($task->getState() == task::PASS) { + $this->countPass++; + } else { + $this->countFail++; + } + + // store result + $index = $task->getIndex(); + + if ($this->groupTasks == true) { + $this->taskList[$type-2][$index] = $task; + logg("RECEIVER store task ".($type-1)."-$index"); + + } else { + $this->taskList[$index] = $task; + logg("RECEIVER store task $index"); + } + + + } + else logg("RECEIVER ERROR $error"); + } + + $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); + + for ($i=1; $i<=$this->processCount; $i++) { + + if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { + + logg("RECEIVER send KILL_CHILD"); + } + else logg("RECEIVER ERROR $error"); + } + + logg("RECEIVER EXIT"); + return; + } + + + /** + * the sender is passes through the task-list and distributes the single + * tasks to the child-processes using the input-queue. + * when finished it terminates itself. + * + * @return void + */ + private function sender() + { + logg("SENDER START - ".sizeof($this->taskList)." tasks"); + + $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); + + for ($i=0; $i<sizeof($this->taskList); $i++) { + + if ($this->groupTasks == true) { + + for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { + + $this->sendTask($this->taskList[$i][$j], $j, $i+1); + } + + } else { + + $this->sendTask($this->taskList[$i], $i); + } + } + + logg("SENDER EXIT"); + exit(0); + } + + + /** + * helper-class of sender. + * sends a task to a child-process using the input-queue. + * + * @param task $task the task to send + * @param int $index the task's index in the taskList + * @param int $type the message-type (default=1) + * @return void + */ + private function sendTask(task $task, $index, $type=1) + { + $task->setIndex($index); + + if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { + + logg("SENDER send task $type - $index"); + } + else logg("SENDER ERROR $error"); + + return; + } + + + /** + * the child is listening to the input-queue and executes the incomming + * tasks. afterwards it setts the task-state and sends it back to the + * receiver via the result-queue. + * after receiving the kill-signal from the receiver it terminates itself. + * + * @param int $cid the child-id (default=NULL) + * @return void + */ + private function child($cid=NULL) + { + if (is_null($cid)) { + $cid = 0; + } + + logg("child $cid START"); + + $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); + $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); + + $type = 1; + + while (true) { + + if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { + + if ($task == self::KILL_CHILD) + break; + + $index = $task->getIndex(); + + logg("child $cid - run task $index"); + + if ($task->run() === true) { + $task->setState(task::PASS); + } else { + $task->setState(task::FAIL); + } + + print "."; + flush(); + + if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { + + logg("child $cid - send task $index"); + } + else logg("child $cid ERROR $error"); + + } + else logg("child $cid ERROR $error"); + } + + logg("child $cid EXIT"); + exit(0); + } + + +} + +?> \ No newline at end of file diff --git a/code-samples/taskScheduler/results.xls b/code-samples/taskScheduler/results.xls new file mode 100644 index 0000000..7bb59be Binary files /dev/null and b/code-samples/taskScheduler/results.xls differ diff --git a/code-samples/taskScheduler/run.php b/code-samples/taskScheduler/run.php index 29b8e17..51aef04 100644 --- a/code-samples/taskScheduler/run.php +++ b/code-samples/taskScheduler/run.php @@ -1,6 +1,8 @@ <?php include 'classes/taskScheduler.php'; +include 'classes/taskSchedulerMsgQ.php'; +include 'classes/taskSchedulerFile.php'; include 'classes/taskInterface.php'; include 'classes/task.php'; @@ -25,14 +27,15 @@ function logg($msg) { $argc = sizeof($argv); -if ($argc >= 2 || $argc <= 3) { +if ($argc >= 2 || $argc <= 4) { $src = $argv[1]; $count = isset($argv[2]) ? $argv[2] : NULL; + $useMsgQ = isset($argv[3]); } else { - die("USAGE: php run.php example processCount\n"); + die("USAGE: php run.php example processCount useMsgQ\n"); } @@ -50,20 +53,21 @@ include $src; $taskList = createTaskList($count); + // init scheduler -$c = new taskScheduler(); +$c = taskScheduler::getInstance($taskList, $count, $useMsgQ); + $c->setTaskList($taskList); $c->setProcessCount($count); $c->run(); -$c->printStatistic(); - -// var_dump($c->getTaskList()); +$c->printStatistic(); $c->printFailedTasks(); - $c->printMemStatistic(10); +// var_dump($c->getTaskList()); + exit(0); ?>