public function scheduleNextRetry(Job $originalJob) { return new \DateTime('+' . pow($this->base, count($originalJob->getRetryJobs())) . ' seconds'); }
public function getJobStatistics(Job $job) { $statisticData = array(); $dataPerCharacteristic = array(); $statistics = $this->em->getConnection()->query("SELECT * FROM jms_job_statistics WHERE job_id = " . $job->getId()); foreach ($statistics as $row) { $dataPerCharacteristic[$row['characteristic']][] = array($row['createdAt'], $row['charValue']); } if ($dataPerCharacteristic) { $statisticData = array(array_merge(array('Time'), $chars = array_keys($dataPerCharacteristic))); $startTime = strtotime($dataPerCharacteristic[$chars[0]][0][0]); $endTime = strtotime($dataPerCharacteristic[$chars[0]][count($dataPerCharacteristic[$chars[0]]) - 1][0]); $scaleFactor = $endTime - $startTime > 300 ? 1 / 60 : 1; // This assumes that we have the same number of rows for each characteristic. for ($i = 0, $c = count(reset($dataPerCharacteristic)); $i < $c; $i++) { $row = array((strtotime($dataPerCharacteristic[$chars[0]][$i][0]) - $startTime) * $scaleFactor); foreach ($chars as $name) { $value = (double) $dataPerCharacteristic[$name][$i][1]; switch ($name) { case 'memory': $value /= 1024 * 1024; break; } $row[] = $value; } $statisticData[] = $row; } } return $statisticData; }
public function getJobStatistics(Job $job) { $statisticData = array(); $dataPerCharacteristic = array(); $stmt = $this->em->getConnection()->prepare('SELECT * FROM jms_job_statistics WHERE job_id = :jobId'); $stmt->execute(array('jobId' => $job->getId())); $statistics = $stmt->fetchAll(); $propertyAccess = PropertyAccess::createPropertyAccessor(); foreach ($statistics as $row) { $dataPerCharacteristic[$propertyAccess->getValue($row, '[characteristic]')][] = array($propertyAccess->getValue($row, '[createdAt]'), $propertyAccess->getValue($row, '[charValue]')); } if ($dataPerCharacteristic) { $statisticData = array(array_merge(array('Time'), $chars = array_keys($dataPerCharacteristic))); $startTime = strtotime($dataPerCharacteristic[$chars[0]][0][0]); $endTime = strtotime($dataPerCharacteristic[$chars[0]][count($dataPerCharacteristic[$chars[0]]) - 1][0]); $scaleFactor = $endTime - $startTime > 300 ? 1 / 60 : 1; // This assumes that we have the same number of rows for each characteristic. for ($i = 0, $c = count(reset($dataPerCharacteristic)); $i < $c; $i++) { $row = array((strtotime($dataPerCharacteristic[$chars[0]][$i][0]) - $startTime) * $scaleFactor); foreach ($chars as $name) { $value = (double) $dataPerCharacteristic[$name][$i][1]; switch ($name) { case 'memory': $value /= 1024 * 1024; break; } $row[] = $value; } $statisticData[] = $row; } } return $statisticData; }
public function testGetRelatedEntities() { $relEntity = new Schedule(); $this->assertInternalType('array', $this->object->getRelatedEntities($this->job)); $this->assertEmpty($this->object->getRelatedEntities($this->job)); $this->job->addRelatedEntity($relEntity); $this->assertNotEmpty($this->object->getRelatedEntities($this->job)); }
public function __construct(Job $job, $newState, array $allowedStates = array()) { $msg = sprintf('The Job(id = %d) cannot change from "%s" to "%s". Allowed transitions: ', $job->getId(), $job->getState(), $newState); $msg .= count($allowedStates) > 0 ? '"' . implode('", "', $allowedStates) . '"' : '#none#'; parent::__construct($msg); $this->job = $job; $this->newState = $newState; $this->allowedStates = $allowedStates; }
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()); }
/** * @param Job $job * @return \Symfony\Component\Process\Process */ public function runJob(Job $job) { $pb = $this->getCommandProcessBuilder(); $pb->add($job->getCommand())->add('--jms-job-id=' . $job->getId()); foreach ($job->getArgs() as $arg) { $pb->add($arg); } $proc = $pb->getProcess(); $proc->start(); return $proc; }
/** * {@inheritdoc} */ public function load(ObjectManager $manager) { foreach ($this->data as $data) { $entity = new Job($data['command'], $data['args'], $data['confirmed']); foreach ($data['state'] as $state) { $entity->setState($state); } $this->setReference($data['reference'], $entity); $manager->persist($entity); } $manager->flush(); }
private function resolveDependencies(EntityManager $em, Job $job) { // If this job has failed, or has otherwise not succeeded, we need to set the // incoming dependencies to failed if that has not been done already. if (!$job->isFinished()) { /** @var JobRepository $repository */ $repository = $em->getRepository('JMS\\JobQueueBundle\\Entity\\Job'); foreach ($repository->findIncomingDependencies($job) as $incomingDep) { if ($incomingDep->isInFinalState()) { continue; } $finalState = Job::STATE_CANCELED; if ($job->isRunning()) { $finalState = Job::STATE_FAILED; } $repository->closeJob($incomingDep, $finalState); } } $em->getConnection()->executeUpdate("DELETE FROM jms_job_dependencies WHERE dest_job_id = :id", array('id' => $job->getId())); }
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()); }
public function testIsRetryAllowed() { $job = new Job('a'); $this->assertFalse($job->isRetryAllowed()); $job->setMaxRetries(1); $this->assertTrue($job->isRetryAllowed()); $job->setState('running'); $retry = new Job('a'); $job->addRetryJob($retry); $this->assertFalse($job->isRetryAllowed()); }
/** * Create JMS jobs for queued process jobs * * @param \Doctrine\ORM\EntityManager $entityManager */ protected function createJobs($entityManager) { if (empty($this->queuedJobs)) { return; } foreach ($this->queuedJobs as $timeShift => $processJobBatch) { foreach ($processJobBatch as $priority => $processJobs) { $args = array(); /** @var ProcessJob $processJob */ foreach ($processJobs as $processJob) { $args[] = '--id=' . $processJob->getId(); $this->logger->debug('Process queued', $processJob->getProcessTrigger(), $processJob->getData()); } $jmsJob = new Job(ExecuteProcessJobCommand::NAME, $args, true, Job::DEFAULT_QUEUE, $priority); if ($timeShift) { $timeShiftInterval = ProcessTrigger::convertSecondsToDateInterval($timeShift); $executeAfter = new \DateTime('now', new \DateTimeZone('UTC')); $executeAfter->add($timeShiftInterval); $jmsJob->setExecuteAfter($executeAfter); } $entityManager->persist($jmsJob); } } $this->queuedJobs = array(); $entityManager->flush(); }
public function testModifyingRelatedEntity() { $wagon = new Wagon(); $train = new Train(); $wagon->train = $train; $defEm = self::$kernel->getContainer()->get('doctrine')->getManager('default'); $defEm->persist($wagon); $defEm->persist($train); $defEm->flush(); $j = new Job('j'); $j->addRelatedEntity($wagon); $this->em->persist($j); $this->em->flush(); $defEm->clear(); $this->em->clear(); $this->assertNotSame($defEm, $this->em); $reloadedJ = $this->em->find('JMSJobQueueBundle:Job', $j->getId()); $reloadedWagon = $reloadedJ->findRelatedEntity('JMS\\JobQueueBundle\\Tests\\Functional\\TestBundle\\Entity\\Wagon'); $reloadedWagon->state = 'broken'; $defEm->persist($reloadedWagon); $defEm->flush(); $this->assertTrue($defEm->contains($reloadedWagon->train)); }
private function getJobIdsOfIncomingDependencies(Job $job) { $jobIds = $this->_em->getConnection()->executeQuery("SELECT source_job_id FROM jms_job_dependencies WHERE dest_job_id = :id", array('id' => $job->getId()))->fetchAll(\PDO::FETCH_COLUMN); return $jobIds; }
/** * @Route("/{id}/retry", name = "jms_jobs_retry_job") */ public function retryJobAction(Job $job) { $state = $job->getState(); if (Job::STATE_FAILED !== $state && Job::STATE_TERMINATED !== $state && Job::STATE_INCOMPLETE !== $state) { throw new HttpException(400, 'Given job can\'t be retried'); } $retryJob = clone $job; $this->getEm()->persist($retryJob); $this->getEm()->flush(); $url = $this->router->generate('jms_jobs_details', array('id' => $retryJob->getId()), false); return new RedirectResponse($url, 201); }
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)); } }
public function addRetryJob(Job $job) { if (self::STATE_RUNNING !== $this->state) { throw new \LogicException('Retry jobs can only be added to running jobs.'); } $job->setOriginalJob($this); $this->retryJobs->add($job); }