Ejemplo n.º 1
0
 /**
  * {@inheritDoc}
  */
 public function createCurrentProcess()
 {
     $process = new Process();
     $process->setPidFromCurrentProcess();
     return $process;
 }
Ejemplo n.º 2
0
 /**
  * Work
  *
  * The primary loop for a worker which when called on an instance starts
  * the worker's life cycle.
  *
  * Queues are checked every $interval (seconds) for new jobs.
  *
  * @param int $interval How often to check for new jobs across the queues. @todo remove, use setInterval or similar
  */
 public function work($interval = 3)
 {
     $this->startup();
     while (true) {
         if ($this->shutdown) {
             break;
         }
         $this->getProcess()->dispatchSignals();
         if ($this->paused) {
             $this->getProcess()->setTitle('Paused');
             if ($interval == 0) {
                 break;
             }
             usleep($interval * 1000000);
             continue;
         }
         try {
             $job = $this->reserve();
         } catch (\Exception $ex) {
             $this->getLogger()->error('Failed to reserve due to exception "{message}", skipping', array('message' => $ex->getMessage()));
             continue;
         }
         if (null === $job) {
             // For an interval of 0, break now - helps with unit testing etc
             // @todo replace with some method, which can be mocked... an interval of 0 should be considered valid
             if ($interval == 0) {
                 break;
             }
             $this->eventDispatcher->dispatch(ResqueWorkerEvents::WAIT_NO_JOB, new WorkerEvent($this));
             $this->getProcess()->setTitle('Waiting for ' . implode(',', $this->queues));
             $this->getLogger()->debug('Sleeping for {seconds}s, no jobs on {queues}', array('queues' => implode(', ', array_map(function ($a) {
                 return $a->getName();
             }, $this->getQueues())), 'seconds' => $interval));
             sleep($interval);
             continue;
         }
         $this->getLogger()->notice('Starting work on {job}', array('job' => $job));
         if ($job instanceof TrackableJobInterface) {
             $job->setState(JobInterface::STATE_PERFORMING);
         }
         $this->setCurrentJob($job);
         if ($this->fork) {
             $this->eventDispatcher->dispatch(ResqueWorkerEvents::BEFORE_FORK_TO_PERFORM, new WorkerJobEvent($this, $job));
             $this->childProcess = $this->getProcess()->fork();
             if (null === $this->childProcess) {
                 // This is child process, it will perform the job and then die.
                 $this->eventDispatcher->dispatch(ResqueWorkerEvents::AFTER_FORK_TO_PERFORM, new WorkerJobEvent($this, $job));
                 // @todo do not construct Process here.
                 $child = new Process();
                 $child->setPidFromCurrentProcess();
                 $this->setProcess($child);
                 $this->perform($job);
                 exit(0);
             } else {
                 // This is the parent.
                 $title = 'Forked ' . $this->childProcess->getPid() . ' at ' . date('c');
                 $this->getProcess()->setTitle($title);
                 $this->getLogger()->debug($title);
                 // Wait until the child process finishes before continuing.
                 $this->childProcess->wait();
                 if (false === $this->childProcess->isCleanExit()) {
                     $exception = new DirtyExitException('Job dirty exited with code ' . $this->childProcess->getExitCode());
                     $this->handleFailedJob($job, $exception);
                 }
             }
             // Child should be dead by now.
             $this->childProcess = null;
         } else {
             $this->perform($job);
         }
         $this->workComplete($job);
     }
 }