public function createCronJob(\DateTime $_) { if (!$this instanceof Command) { throw new \LogicException('This trait must be used in Symfony console commands only.'); } $job = new Job($this->getName()); $job->setMaxRuntime((int) min(300, $this->getScheduleInterval())); return $job; }
public function testJobIsTerminatedIfMaxRuntimeIsExceeded() { $this->markTestSkipped('Requires a patched Process class (see symfony/symfony#5030).'); $job = new Job('jms-job-queue:never-ending'); $job->setMaxRuntime(1); $this->em->persist($job); $this->em->flush($job); $this->doRun(array('--max-runtime' => 1)); $this->assertEquals('terminated', $job->getState()); }
private function closeJobInternal(Job $job, $finalState, array &$visited = array()) { if (in_array($job, $visited, true)) { return; } $visited[] = $job; if (null !== $this->dispatcher && ($job->isRetryJob() || 0 === count($job->getRetryJobs()))) { $event = new StateChangeEvent($job, $finalState); $this->dispatcher->dispatch('jms_job_queue.job_state_change', $event); $finalState = $event->getNewState(); } switch ($finalState) { case Job::STATE_CANCELED: $job->setState(Job::STATE_CANCELED); $this->_em->persist($job); if ($job->isRetryJob()) { $this->closeJobInternal($job->getOriginalJob(), Job::STATE_CANCELED, $visited); return; } foreach ($this->findIncomingDependencies($job) as $dep) { $this->closeJobInternal($dep, Job::STATE_CANCELED, $visited); } return; case Job::STATE_FAILED: case Job::STATE_TERMINATED: case Job::STATE_INCOMPLETE: if ($job->isRetryJob()) { $job->setState($finalState); $this->_em->persist($job); $this->closeJobInternal($job->getOriginalJob(), $finalState); return; } // The original job has failed, and we are allowed to retry it. if ($job->isRetryAllowed()) { $retryJob = new Job($job->getCommand(), $job->getArgs()); $retryJob->setMaxRuntime($job->getMaxRuntime()); $job->addRetryJob($retryJob); $this->_em->persist($retryJob); $this->_em->persist($job); return; } $job->setState($finalState); $this->_em->persist($job); // The original job has failed, and no retries are allowed. foreach ($this->findIncomingDependencies($job) as $dep) { $this->closeJobInternal($dep, Job::STATE_CANCELED, $visited); } return; case Job::STATE_FINISHED: if ($job->isRetryJob()) { $job->getOriginalJob()->setState($finalState); $this->_em->persist($job->getOriginalJob()); } $job->setState($finalState); $this->_em->persist($job); return; default: throw new \LogicException(sprintf('Non allowed state "%s" in closeJobInternal().', $finalState)); } }
private function closeJobInternal(Job $job, $finalState, array &$visited = array()) { if (in_array($job, $visited, true)) { return; } $visited[] = $job; if ($job->isInFinalState()) { return; } if (null !== $this->dispatcher && ($job->isRetryJob() || 0 === count($job->getRetryJobs()))) { $event = new StateChangeEvent($job, $finalState); $this->dispatcher->dispatch('jms_job_queue.job_state_change', $event); $finalState = $event->getNewState(); } switch ($finalState) { case Job::STATE_CANCELED: $job->setState(Job::STATE_CANCELED); $this->_em->persist($job); if ($job->isRetryJob()) { $this->closeJobInternal($job->getOriginalJob(), Job::STATE_CANCELED, $visited); return; } foreach ($this->findIncomingDependencies($job) as $dep) { $this->closeJobInternal($dep, Job::STATE_CANCELED, $visited); } return; case Job::STATE_FAILED: case Job::STATE_TERMINATED: case Job::STATE_INCOMPLETE: if ($job->isRetryJob()) { $job->setState($finalState); $this->_em->persist($job); $this->closeJobInternal($job->getOriginalJob(), $finalState); return; } // The original job has failed, and we are allowed to retry it. if ($job->isRetryAllowed()) { $retryJob = new Job($job->getCommand(), $job->getArgs()); $retryJob->setMaxRuntime($job->getMaxRuntime()); if ($this->retryScheduler === null) { $this->retryScheduler = new ExponentialRetryScheduler(5); } $retryJob->setExecuteAfter($this->retryScheduler->scheduleNextRetry($job)); $job->addRetryJob($retryJob); $this->_em->persist($retryJob); $this->_em->persist($job); return; } $job->setState($finalState); $this->_em->persist($job); // The original job has failed, and no retries are allowed. foreach ($this->findIncomingDependencies($job) as $dep) { // This is a safe-guard to avoid blowing up if there is a database inconsistency. if (!$dep->isPending() && !$dep->isNew()) { continue; } $this->closeJobInternal($dep, Job::STATE_CANCELED, $visited); } return; case Job::STATE_FINISHED: if ($job->isRetryJob()) { $job->getOriginalJob()->setState($finalState); $this->_em->persist($job->getOriginalJob()); } $job->setState($finalState); $this->_em->persist($job); return; default: throw new \LogicException(sprintf('Non allowed state "%s" in closeJobInternal().', $finalState)); } }
public function testJobIsTerminatedIfMaxRuntimeIsExceeded() { $job = new Job('jms-job-queue:never-ending'); $job->setMaxRuntime(1); $this->em->persist($job); $this->em->flush($job); $this->doRun(array('--max-runtime' => 1, '--worker-name' => 'test')); $this->assertEquals('terminated', $job->getState()); }