getServiceLocator()->get(WorkerProcessManager::SERVICE_ID); $workerManager->setLimitOfCpu($this->getOption('limitOfCpu')); $workerManager->setLimitOfMemory($this->getOption('limitOfMemory')); /** @var TaskSerializerService $taskSerializer */ $taskSerializer = $this->getServiceLocator()->get(TaskSerializerService::SERVICE_ID); $queueService = $this->getQueueService(); $loop = Factory::create(); $interval = $this->getOption('interval'); $loop->addPeriodicTimer($interval, function () use ($loop, $queueService, $taskSerializer, $workerManager) { if ($workerManager->canRun()) { $task = $queueService->dequeue(); if ($task !== null) { $cmd = $workerManager->getCommand(); $taskJson = base64_encode($taskSerializer->serialize($task)); $cmd = 'cd ' . ROOT_PATH . ' && ' . $cmd . ' -t ' . $taskJson; $process = new \React\ChildProcess\Process($cmd); $process->start($loop); $workerManager->addProcess($process); } unset($task); } }); $loop->run(); } /** * @return \common_report_Report|QueueDispatcherInterface * @throws \Exception */ protected function getQueueService() { /** @var QueueDispatcherInterface $queueService */ $queueService = $this->getServiceLocator()->get(QueueDispatcherInterface::SERVICE_ID); if ($queueService->isSync()) { throw new \Exception('No worker is needed because all registered queue is a Sync Queue.'); } return $queueService; } protected function provideOptions() { return [ 'interval' => [ 'prefix' => 'i', 'longPrefix' => 'interval', 'cast' => 'integer', 'required' => true, 'description' => 'The interval to run a task.' ], 'limitOfCpu' => [ 'prefix' => 'cpu', 'longPrefix' => 'limitOfCpu', 'cast' => 'integer', 'required' => true, 'description' => 'CPU Limit percentage' ], 'limitOfMemory' => [ 'prefix' => 'm', 'longPrefix' => 'limitOfMemory', 'cast' => 'integer', 'required' => true, 'description' => 'Memory limit percentage' ] ]; } /** * @return string */ protected function provideDescription() { return 'Run tasks as a new fork process'; } }