Kohkimakimoto\Worker\Job\JobManager::executeJob PHP Method

executeJob() public method

public executeJob ( $job, $oneTime = false, $passdArguments = [] )
    public function executeJob($job, $oneTime = false, $passdArguments = array())
    {
        $id = $job->getId();
        $name = $job->getName();
        $output = $this->output;
        $now = new \DateTime();
        if ($output->isDebug()) {
            $output->writeln("[debug] Try running a job: {$name} at " . $now->format('Y-m-d H:i:s'));
        }
        $pid = pcntl_fork();
        if ($pid === -1) {
            // Error
            throw new \RuntimeException("pcntl_fork error.");
        } elseif ($pid) {
            // Parent process
            $status = null;
            $pid = pcntl_wait($status);
            if (!$pid) {
                throw new \RuntimeException("pcntl_wait error.");
            }
            $job->setLastRunTime($now);
            // add next timer
            if ($job->hasCronTime() && !$oneTime) {
                $this->addJobTimer($job);
            }
        } else {
            // Child process
            // Remove tty to ignore signals from tty.
            posix_setsid();
            // Stops copied event loop.
            $this->eventLoop->stop();
            unset($this->eventLoop);
            $this->dispatcher->dispatch(JobEvents::FORKED_PROCESS, new JobForkedProcessEvent($this->worker, $job));
            // Forks it one more time to prevent to be zombie process.
            $pid = pcntl_fork();
            if ($pid === -1) {
                // Error
                throw new \RuntimeException("pcntl_fork error.");
            } elseif ($pid) {
                exit;
            }
            if ($output->isDebug()) {
                $output->writeln("[debug] Forked process for: {$name} (pid:" . posix_getpid() . ")");
            }
            if ($job->isLimitOfProcesses()) {
                $output->writeln("<fg=magenta>Skip the job '{$name}' due to limit of max processes: " . $job->getMaxProcesses() . " at " . (new \DateTime())->format('Y-m-d H:i:s') . "</fg=magenta>");
                exit;
            }
            $output->writeln("<info>Runs job:</info> <comment>{$name}</comment> (pid: " . posix_getpid() . ") at " . (new \DateTime())->format('Y-m-d H:i:s'));
            $job->addRuntimeEntryToJobInfo($pid);
            $command = $job->getCommand();
            if ($command instanceof \Closure) {
                // command is a closure
                $arguments = array();
                $parameters = $job->getCommandParameters();
                if ($parameters) {
                    foreach ($parameters as $parameter) {
                        $class = $parameter->getClass();
                        if ($class && $class->getName() === 'Kohkimakimoto\\Worker\\Worker') {
                            $arguments[] = $this->worker;
                            continue;
                        }
                        $argName = $parameter->getName();
                        if (isset($passdArguments[$argName])) {
                            $arguments[] = $passdArguments[$argName];
                        } else {
                            $isOptional = $parameter->isOptional();
                            if (!$isOptional) {
                                $arguments[] = null;
                            }
                        }
                    }
                }
                call_user_func_array($command, $arguments);
            } elseif (is_string($command)) {
                // command is a string
                $process = new Process($command);
                $process->setTimeout(null);
                $process->run(function ($type, $buffer) use($output) {
                    $output->write($buffer);
                });
            } else {
                throw new \RuntimeException("Unsupported operation.");
            }
            $job->deleteRuntimeEntryToJobInfo($pid);
            $output->writeln("<info>Finished job:</info> <comment>{$name}</comment> (pid: " . posix_getpid() . ") at " . (new \DateTime())->format('Y-m-d H:i:s'));
            exit;
        }
    }