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));
     }
 }
예제 #4
0
 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));
     }
 }
예제 #5
0
 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());
 }