Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
<?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()
        );
    }

}