Cronario\Manager::run PHP Method

run() public method

public run ( ) : boolean
return boolean
    public function run()
    {
        $file = $this->getBootstrapFile();
        require_once $file;
        $this->startManagerLive();
        $workerClass = $this->getWorkerClass();
        $managerId = $this->getId();
        $logger = $this->getLogger();
        $queue = $this->getQueue();
        $logger->info("Manager {$managerId} start work {$workerClass}", [__NAMESPACE__]);
        try {
            $worker = AbstractWorker::factory($workerClass);
        } catch (Exception\WorkerException $ex) {
            $queue->stop($workerClass);
            $logger->warning($ex->getMessage(), [__NAMESPACE__]);
            $logger->info("Manager {$managerId} Queue stop {$workerClass}", [__NAMESPACE__]);
            $logger->info("Manager {$managerId} finish work {$workerClass}", [__NAMESPACE__]);
            return false;
        }
        try {
            $waitForJob = $this->getWorkerConfig(AbstractWorker::CONFIG_P_MANAGER_IDLE_DIE_DELAY);
            while ($jobId = $queue->reserveJob($workerClass, $waitForJob)) {
                if ($jobId === false) {
                    $logger->debug("Manager {$managerId} queue is empty so {$workerClass}", [__NAMESPACE__]);
                    break;
                }
                $logger->debug("Manager {$managerId} reserve job {$jobId}", [__NAMESPACE__]);
                $job = null;
                try {
                    /** @var AbstractJob $job */
                    $job = Facade::getStorage($this->getAppId())->find($jobId);
                } catch (JobException $ex) {
                    $logger->warning($ex->getMessage(), [__NAMESPACE__]);
                    $queue->deleteJob($jobId);
                    continue;
                }
                if ($job === null) {
                    $logger->error("Manager {$managerId} job is not instanceof of AbstractJob {$jobId}", [__NAMESPACE__]);
                    $queue->deleteJob($jobId);
                    continue;
                }
                $logger->debug("Manager {$managerId} Worker start working at {$jobId}...", [__NAMESPACE__]);
                // DO JOB!
                /** @var ResultException $result */
                $result = $worker($job);
                $logger->debug("Manager {$managerId}  Worker finish working at {$jobId} : {$result->getGlobalCode()}", [__NAMESPACE__]);
                if ($result instanceof ResultException) {
                    if ($result->isSuccess()) {
                        $queue->deleteJob($jobId);
                        $logger->debug("Manager {$managerId} Job ResultException isSuccess {$jobId}", [__NAMESPACE__]);
                        $this->eventTrigger(self::EVENT_SUCCESS);
                    } elseif ($result->isFailure()) {
                        $queue->deleteJob($jobId);
                        $logger->debug("Manager {$managerId} Job ResultException isFail {$jobId}", [__NAMESPACE__]);
                        $this->eventTrigger(self::EVENT_FAIL);
                    } elseif ($result->isError()) {
                        $queue->buryJob($jobId);
                        $logger->debug("Manager {$managerId} Job ResultException isError {$jobId}", [__NAMESPACE__]);
                        $this->eventTrigger(self::EVENT_ERROR);
                    } elseif ($result->isRetry()) {
                        $logger->debug("Manager {$managerId} Job ResultException isRetry {$jobId}", [__NAMESPACE__]);
                        $job->addAttempts();
                        $job->save();
                        // important this will saved result to job !!!
                        $attemptCount = $job->getAttempts();
                        $attemptDelay = $job->countAttemptQueueDelay();
                        // can be new worker class "like redirect in sms/alpha to sms"
                        $gatewayClass = $job->getWorkerClass();
                        $queue->deleteJob($jobId);
                        if ($job->hasAttempt()) {
                            $logger->debug("job {$jobId} has {$attemptCount} attempts (max:{$job->getAttemptsMax()}) and will be delayed {$attemptDelay}", [__NAMESPACE__]);
                            $queue->putJob($gatewayClass, $jobId, $attemptDelay);
                            $this->eventTrigger(self::EVENT_RETRY);
                        } else {
                            $logger->debug("job {$jobId} has {$attemptCount} attempts (max:{$job->getAttemptsMax()})  and will have bad result", [__NAMESPACE__]);
                            $job->setResult(new ResultException(ResultException::FAILURE_MAX_ATTEMPTS));
                            $job->save();
                            $this->eventTrigger(self::EVENT_FAIL);
                        }
                    } elseif ($result->isRedirect()) {
                        $queue->deleteJob($jobId);
                        $queue->putJob($job->getWorkerClass(), $jobId);
                        $logger->debug("Job ResultException isRedirect {$jobId} to {$job->getWorkerClass()}", [__NAMESPACE__]);
                        $this->eventTrigger(self::EVENT_REDIRECT);
                    } else {
                        $queue->deleteJob($jobId);
                        $logger->error("Undefined result job id : {$jobId}", [__NAMESPACE__]);
                    }
                } else {
                    $logger->error('job result is not type of AbstractResultException', [__NAMESPACE__]);
                }
                if ($job->getSchedule()) {
                    $newJob = clone $job;
                    $newJob();
                    $logger->debug("Manager {$managerId} catch daemon  shutdown, finish listening queue", [__NAMESPACE__]);
                }
                if ($this->isLimitsExceeded() || $this->isProducerShutDown()) {
                    break;
                }
                $this->waitDelay();
            }
        } catch (\Exception $ex) {
            $logger->warning($ex->getMessage());
        }
        $logger->info("Manager {$managerId} finish work {$workerClass}", [__NAMESPACE__]);
        $this->finishManagerLive();
        return true;
    }