/** * * @return ResultCollection */ public function getResultCollection() { $pool = new WorkerPool(); $pool->setWorkerPoolSize($this->processCollection->count())->create(new ClosureWorker(function (Process $process) { $result = new Result(); $result->setProcess($process); try { if (!class_exists($process->getClass())) { throw new \Exception(sprintf('Invalid class provided: "%s"', $process->getClass())); } $class = $process->getClass(); $class = new $class(); $result->setData($class->process($process->getData())); $result->setSuccessful(true); } catch (\Exception $e) { $result->setErrorMessage($e->getMessage()); } return $result; })); foreach ($this->processCollection as $process) { $pool->run($process); } $pool->waitForAllWorkers(); $resultCollection = new ResultCollection(); foreach ($pool as $result) { $resultEntity = new Result(); if (!empty($result['data'])) { $resultEntity = $result['data']; } elseif (!empty($result['workerException']['message'])) { $resultEntity->setErrorMessage($result['workerException']['message']); } elseif (!empty($result['poolException']['message'])) { $resultEntity->setErrorMessage($result['poolException']['message']); } else { $resultEntity->setErrorMessage(self::INTERNAL_ERROR); } $resultCollection->add($resultEntity); } return $resultCollection; }
public function testPingWorkers() { try { $wp = new WorkerPool(); $wp->setWorkerPoolSize(50); $wp->create(new Fixtures\PingWorker()); $failCount = 0; for ($i = 0; $i < 500; $i++) { $wp->run($i); $a = $wp->getFreeAndBusyWorkers(); if ($a['free'] + $a['busy'] != $a['total']) { $failCount++; } } $wp->waitForAllWorkers(); $this->assertLessThanOrEqual(0, $failCount, 'Sometimes the sum of free and busy workers does not equal to the pool size.'); $this->assertEquals(500, count($wp), 'The result count should be 500.'); $i = 0; foreach ($wp as $val) { $i++; } $this->assertEquals(500, $i, 'We should have 500 results in the pool.'); $this->assertEquals(0, count($wp), 'The result count should be 0 now.'); } catch (\Exception $e) { $this->assertTrue(FALSE, 'An unexpected exception was thrown.'); } try { $wp->destroy(); } catch (\Exception $e) { $this->assertTrue(FALSE, 'WorkerPool::Destroy shouldn\\t throw an exception of type ' . get_class($e) . ' with message:' . $e->getMessage() . "\n" . $e->getTraceAsString()); } }
<?php /** * Thisfile requires the jeremeamia/SuperClosure */ require_once __DIR__ . '/../autoload.php'; if (file_exists(__DIR__ . '/../../../autoload.php')) { require_once __DIR__ . '/../../../autoload.php'; } else { die("Cannot find a classloader for jeremeamia/SuperClosure!\n"); } use QXS\WorkerPool\WorkerPool, QXS\WorkerPool\SuperClosureWorker, QXS\WorkerPool\SerializableWorkerClosure; $wp = new WorkerPool(); $wp->setWorkerPoolSize(4)->create(new SuperClosureWorker()); for ($i = 0; $i < 10; $i++) { $wp->run(new SerializableWorkerClosure(function ($input, $semaphore, $storage) use($i) { if ($i % 2) { echo "CHILD " . getmypid() . " CODE using {$i} - received input {$input} ...\n"; } else { echo "child " . getmypid() . " Code using {$i} - received input {$input} ...\n"; } return $input / 2; }, $i * 2)); } $wp->waitForAllWorkers(); // wait for all workers foreach ($wp as $val) { echo "MASTER RECEIVED " . $val['data'] . "\n"; }