예제 #1
0
 public function execute(Job $job, $force = false)
 {
     $className = App::className($job->getWorker(), 'Worker', 'Worker');
     if (!class_exists($className)) {
         throw new JobExecuteException("Worker does not exist (" . $className . ")");
     }
     $jobWorker = new $className();
     if (!$jobWorker instanceof JobWorkerInterface) {
         throw new JobExecuteException("Worker class '{$className}' does not follow the required 'JobWorkerInterface");
     }
     $this->djLog(__('Received job {0}.', $job->getId()));
     $event = $this->dispatchEvent('DelayedJob.beforeJobExecute', [$job]);
     if ($event->isStopped()) {
         //@TODO: Requeue job if queueable job
         return $event->result;
     }
     if ($force === false && ($job->getStatus() === Job::STATUS_SUCCESS || $job->getStatus() === Job::STATUS_BURRIED)) {
         $this->djLog(__('Job {0} has already been processed', $job->getId()));
         $this->getMessageBroker()->ack($job);
         return true;
     }
     if ($force === false && $job->getStatus() === Job::STATUS_BUSY) {
         $this->djLog(__('Job {0} has already being processed', $job->getId()));
         $this->getMessageBroker()->ack($job);
         return true;
     }
     $this->lock($job);
     $event = null;
     $result = false;
     $start = microtime(true);
     try {
         $result = $jobWorker($job);
         $duration = round((microtime(true) - $start) * 1000);
         $this->completed($job, $result, $duration);
     } catch (\Error $error) {
         //## Job Failed badly
         $result = $error;
         $this->failed($job, $error, true);
         Log::emergency(sprintf("Delayed job %d failed due to a fatal PHP error.\n%s\n%s", $job->getId(), $error->getMessage(), $error->getTraceAsString()));
     } catch (\Exception $exc) {
         //## Job Failed
         $result = $exc;
         $this->failed($job, $exc, $exc instanceof NonRetryableException);
     } finally {
         $this->getMessageBroker()->ack($job);
         $duration = $duration ?? round((microtime(true) - $start) * 1000);
         $this->dispatchEvent('DelayedJob.afterJobExecute', [$job, $result, $duration]);
     }
     return $result;
 }