public function onMessage(Message $message)
    {
        $this->stopwatch->start('processMessage');

        $job = $this->findJob($message->getTicket());

        if ($job->getStatus() == Status::PROCESSING() || $job->getStatus() == Status::CANCELLED() || $job->getStatus() == Status::ERROR()) {

            $this->logger->notice(sprintf('Skipped execution of job %s (status: %s)', $job->getTicket(), $job->getStatus()));

            return;
        }
        try {
            $this->locker->lock($this->getLockName($job));
        } catch (LockException $e) {
            $this->logger->warning('Failed to get lock for job ' . $job->getTicket());

            return;
        }

        $event = new ExecutionEvent($job, new Context());

        $this->dispatchExecutionEvent(JobEvents::JOB_PRE_EXECUTE, $event);

        $job->setStatus(Status::PROCESSING());
        $job->setProcessingTime(0);
        $this->jobManager->save($job);

        $response       = null;
        $this->stopwatch->start('processJob');

        try {
            $this->logger->debug(sprintf('Execute job %s of type "%s"', $job->getTicket(), $job->getType()), [
                'parameters' => $job->getParameters()
            ]);

            // invoke the job
            $response = $this->invoker->invoke($job, $event->getContext());

            if ($job->getStatus() != Status::CANCELLED()) {
                $status = $job->hasSchedules() ? Status::SLEEPING() : Status::PROCESSED();
            } else {
                $status = Status::CANCELLED();
            }

            $this->dispatchExecutionEvent(JobEvents::JOB_POST_EXECUTE, $event);
        }
        catch (\Throwable $e)
        {
            $this->logger->warning(sprintf('Failed to execute job %s (Error: $s)', $job->getTicket(), $e->getMessage()), [
                'job'       => $job,
                'exception' => $e
            ]);

            $this->getJobLogger($job)->error($e->getMessage(), ['exception' => $e]);

            $response = new ExceptionResponse($e);
            $status   = Status::ERROR();
        }
        catch (\Exception $e)
        {
            $this->logger->warning(sprintf('Failed to execute job %s (Error: $s)', $job->getTicket(), $e->getMessage()), [
                'job'       => $job,
                'exception' => $e
            ]);

            $this->getJobLogger($job)->error($e->getMessage(), ['exception' => $e]);

            $response = new ExceptionResponse($e);
            $status   = Status::ERROR();
        }

        $this->releaseLock($job);

        $this->helper->updateJob($job, $status, $this->stopwatch->stop('processJob')->getDuration(), $response);
        $this->jobManager->save($job);

        if (Status::isTerminated($job->getStatus())) {
            $this->dispatcher->dispatch(JobEvents::JOB_TERMINATED, new TerminationEvent($job));
        }
    }
public function onMessage(Message $message)
    {
        $this->stopwatch->start('processMessage');

        $job = $this->findJob($message->getTicket());

        if ($job->getStatus() == Status::PROCESSING() || $job->getStatus() == Status::CANCELLED() || $job->getStatus() == Status::ERROR()) {

            $this->logger->notice(sprintf('Skipped execution of job %s (status: %s)', $job->getTicket(), $job->getStatus()));

            return;
        }
        try {
            $this->locker->lock($this->getLockName($job));
        } catch (LockException $e) {
            $this->logger->warning('Failed to get lock for job ' . $job->getTicket());

            return;
        }

        $event = new ExecutionEvent($job, new Context());

        $this->dispatchExecutionEvent(JobEvents::JOB_PRE_EXECUTE, $event);

        $job->setStatus(Status::PROCESSING());
        $job->setProcessingTime(0);
        $this->jobManager->save($job);

        $response       = null;
        $this->stopwatch->start('processJob');

        try {
            $this->logger->debug(sprintf('Execute job %s of type "%s"', $job->getTicket(), $job->getType()), [
                'parameters' => $job->getParameters()
            ]);

            // invoke the job
            $response = $this->invoker->invoke($job, $event->getContext());

            if ($job->getStatus() != Status::CANCELLED()) {
                $status = $job->hasSchedules() ? Status::SLEEPING() : Status::PROCESSED();
            } else {
                $status = Status::CANCELLED();
            }

            $this->dispatchExecutionEvent(JobEvents::JOB_POST_EXECUTE, $event);
        }
        catch (\Throwable $e)
        {
            $this->logger->warning(sprintf('Failed to execute job %s (Error: $s)', $job->getTicket(), $e->getMessage()), [
                'job'       => $job,
                'exception' => $e
            ]);

            $this->getJobLogger($job)->error($e->getMessage(), ['exception' => $e]);

            $response = new ExceptionResponse($e);
            $status   = Status::ERROR();
        }
        catch (\Exception $e)
        {
            $this->logger->warning(sprintf('Failed to execute job %s (Error: $s)', $job->getTicket(), $e->getMessage()), [
                'job'       => $job,
                'exception' => $e
            ]);

            $this->getJobLogger($job)->error($e->getMessage(), ['exception' => $e]);

            $response = new ExceptionResponse($e);
            $status   = Status::ERROR();
        }

        $this->releaseLock($job);

        $this->helper->updateJob($job, $status, $this->stopwatch->stop('processJob')->getDuration(), $response);
        $this->jobManager->save($job);

        if (Status::isTerminated($job->getStatus())) {
            $this->dispatcher->dispatch(JobEvents::JOB_TERMINATED, new TerminationEvent($job));
        }
    }
{@inheritdoc}