public function testOnMessageNotUpdatesStatusIfJobWasCancelled() { $job = new Job(); $message = new Message('type', 'ticket'); $this->jobManager->expects($this->once())->method('findByTicket')->with($message->getTicket())->willReturn($job); $this->invoker->expects($this->once())->method('invoke')->willReturnCallback(function (Job $job) { $job->setStatus(Status::CANCELLED()); }); $this->expectsCallsUpdateJob($job, Status::CANCELLED()); $this->subject->onMessage($message); }
/** * {@inheritdoc} */ 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)); } }
/** * @param $withLogger * @dataProvider provideTrueFalse */ public function testInvokeHandlesLoggerAwareJobs($withLogger) { $serviceId = 'serviceId'; $type = 'callable-type'; $callable = new LoggerAwareJob(); $jobType = new JobType($serviceId, $type, array($callable, 'execute')); $logger = $this->createMock(LoggerInterface::class); $context = new Context($withLogger ? ['abc.logger' => $logger] : []); $job = new Job($type); $this->registry->register($jobType); $this->assertEquals('foobar', $this->subject->invoke($job, $context)); if ($withLogger) { $this->assertSame($logger, $callable->getLogger()); } else { $this->assertNull($callable->getLogger()); } }
/** * Resolves the parameters of a job. * * @param string $type The job type * @param array $parameters The job parameters * @return array The parameters the job can be invoked with */ public function resolveParameters($type, array $parameters) { // serialize/deserialize parameters $deserializedParameters = $parameters; if (count($parameters) > 0) { $data = static::getSerializationHelper()->serializeParameters($type, $parameters); /** * @var array $deserializedParameters */ $deserializedParameters = static::getSerializationHelper()->deserializeParameters($type, $data); } // Dispatch event to let listeners register runtime parameters $job = new Job(); $job->setType($type); $job->setParameters($deserializedParameters); $event = new ExecutionEvent($job, new Context()); static::getDispatcher()->dispatch(JobEvents::JOB_PRE_EXECUTE, $event); return Invoker::resolveParameters(static::getJobType($type), $event->getContext(), $deserializedParameters); }