Repository URL to install this package:
|
Version:
6.2.3 ▾
|
<?php
namespace JMS\JobQueueBundle\Controller;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use JMS\JobQueueBundle\Entity\Job;
use JMS\JobQueueBundle\Entity\Repository\JobManager;
use JMS\JobQueueBundle\View\JobFilter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Routing\Annotation\Route;
class JobController extends AbstractController
{
/**
* @Route("/", name = "jms_jobs_overview")
*/
#[Route("/", name: "jms_jobs_overview")]
public function overviewAction(Request $request)
{
$jobFilter = JobFilter::fromRequest($request);
$qb = $this->getEm()->createQueryBuilder();
$qb->select('j')->from(Job::class, 'j')
->where($qb->expr()->isNull('j.originalJob'))
->orderBy('j.id', 'desc');
$lastJobsWithError = $jobFilter->isDefaultPage() ? $this->getRepo()->findLastJobsWithError(5) : [];
foreach ($lastJobsWithError as $i => $job) {
$qb->andWhere($qb->expr()->neq('j.id', '?' . $i));
$qb->setParameter($i, $job->getId());
}
if (!empty($jobFilter->command)) {
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->like('j.command', ':commandQuery'),
$qb->expr()->like('j.args', ':commandQuery')
)
)
->setParameter('commandQuery', '%' . $jobFilter->command . '%');
}
if (!empty($jobFilter->state)) {
$qb->andWhere($qb->expr()->eq('j.state', ':jobState'))
->setParameter('jobState', $jobFilter->state);
}
$perPage = 50;
$query = $qb->getQuery();
$query->setMaxResults($perPage + 1);
$query->setFirstResult(($jobFilter->page - 1) * $perPage);
$jobs = $query->getResult();
return $this->render(
'@JMSJobQueue/job/overview.html.twig',
array(
'jobsWithError' => $lastJobsWithError,
'jobs' => array_slice($jobs, 0, $perPage),
'jobFilter' => $jobFilter,
'hasMore' => count($jobs) > $perPage,
'jobStates' => Job::getStates(),
)
);
}
/**
* @Route("/{id}", name = "jms_jobs_details")
*/
#[Route("/{id}", name: "jms_jobs_details")]
public function detailsAction(Job $job)
{
$relatedEntities = array();
foreach ($job->getRelatedEntities() as $entity) {
$class = ClassUtils::getClass($entity);
$relatedEntities[] = array(
'class' => $class,
'id' => json_encode(
$this->container->get('doctrine')->getManagerForClass($class)->getClassMetadata($class)->getIdentifierValues(
$entity
)
),
'raw' => $entity,
);
}
$statisticData = $statisticOptions = array();
if ($this->getParameter('jms_job_queue.statistics')) {
$dataPerCharacteristic = array();
foreach (
$this->container->get('doctrine')->getManagerForClass(Job::class)->getConnection()->executeQuery(
"SELECT * FROM jms_job_statistics WHERE job_id = " . $job->getId()
)->fetchAllAssociative() as $row
) {
$dataPerCharacteristic[$row['characteristic']][] = array(
// hack because postgresql lower-cases all column names.
array_key_exists('createdAt', $row) ? $row['createdAt'] : $row['createdat'],
array_key_exists('charValue', $row) ? $row['charValue'] : $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 = (float)$dataPerCharacteristic[$name][$i][1];
switch ($name) {
case 'memory':
$value /= 1024 * 1024;
break;
}
$row[] = $value;
}
$statisticData[] = $row;
}
}
}
return $this->render(
'@JMSJobQueue/job/details.html.twig',
array(
'job' => $job,
'relatedEntities' => $relatedEntities,
'incomingDependencies' => $this->getRepo()->getIncomingDependencies($job),
'statisticData' => $statisticData,
'statisticOptions' => $statisticOptions,
)
);
}
/**
* @Route("/{id}/retry", name = "jms_jobs_retry_job")
*/
#[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->generateUrl('jms_jobs_details', array('id' => $retryJob->getId()));
return new RedirectResponse($url, 201);
}
private function getEm(): EntityManagerInterface
{
return $this->container->get('doctrine')->getManagerForClass(Job::class);
}
private function getRepo(): JobManager
{
return $this->container->get('jms_job_queue.job_manager');
}
public static function getSubscribedServices(): array
{
return array_merge(
[
'doctrine' => ManagerRegistry::class,
'jms_job_queue.job_manager' => JobManager::class
],
parent::getSubscribedServices()
);
}
}