/** * {@inheritDoc} */ public function statsJob($job) { if ($this->dispatcher) { $this->dispatcher->dispatch(CommandEvent::STATS_JOB, new CommandEvent($this, ['job' => $job])); } return $this->pheanstalk->statsJob($job); }
/** * Delete given job and create new job with old or passed params * * @param int $jobId * @param int $priority * @param int $delay */ public function reschedule($jobId, $priority = NULL, $delay = NULL) { /** @var Job $job */ $job = $this->pheanstalk->peek($jobId); $jobStats = $this->pheanstalk->statsJob($job); $this->pheanstalk->useTube($this->tube); $priority = NULL === $priority ? $jobStats['pri'] : $priority; $delay = NULL === $delay ? $jobStats['delay'] : $delay; $newJobId = $this->pheanstalk->put($job->getData(), $priority, $delay, $jobStats['ttr']); $this->pheanstalk->delete($job); $context = ['job_id' => $newJobId, 'old_job_id' => $jobId, 'text' => $job->getData(), 'priority' => $priority, 'delay' => $delay]; $this->logger->info(sprintf('Reschedule job (%d => %d): %s', $jobId, $newJobId, $job->getData()), $context); }
/** * @param Job $job The job to process * @param int $maxRetries The number of retries for this job * * @throws AbortException * * @return bool|mixed The executor result if successful, false otherwise */ public function executeJob(Job $job, $maxRetries = 1) { $this->dispatcher->dispatch(WorkerEvents::EXECUTE_JOB, new JobEvent($job)); $stats = $this->pheanstalk->statsJob($job); $payload = (array) json_decode($job->getData(), true); $releases = intval($stats['releases']); $priority = intval($stats['pri']); // context for logging $context = ['tube' => $stats['tube'], 'payload' => $payload, 'attempt' => $releases + 1]; try { // execute command $result = $this->execute($stats['tube'], $payload); // delete job if it completed without exceptions $this->delete($job); return $result; } catch (RescheduleException $re) { // reschedule the job $this->reschedule($job, $re->getRescheduleDate(), $priority); } catch (AbortException $e) { // abort thrown from executor, rethrow it and let the caller handle it throw $e; } catch (\Exception $e) { // some other exception occured $message = sprintf('Exception occurred: %s in %s on line %d', $e->getMessage(), $e->getFile(), $e->getLine()); $this->logJob($job->getId(), $message, LogLevel::ERROR, $context); $this->logJob($job->getId(), $e->getTraceAsString(), LogLevel::DEBUG, $context); // see if we have any retries left if ($releases > $maxRetries) { // no more retries, bury job for manual inspection $this->bury($job); $this->dispatcher->dispatch(WorkerEvents::JOB_BURIED_EVENT, new JobBuriedEvent($job, $e, $releases)); } else { // try again, regardless of the error $this->reschedule($job, new \DateTime('+10 minutes'), $priority); } } return false; }