public function run() { while (true) { $this->scaleAllQueues(); // @todo does detectHungJobs() need a different frequency? $this->detectHungJobs(); JQWorker::sleep($this->scalerPollingInterval); } print "Autoscaler exiting.\n"; }
/** * Starts the worker process. * * Blocks until the worker exists. */ public function start() { $this->log("Starting worker process on queue: " . ($this->options['queueName'] === NULL ? '(any)' : $this->options['queueName'])); if ($this->options['enableJitter']) { $ms = rand(0, 999); $this->log("Startup jitter: 0.{$ms} seconds..."); JQWorker::sleep(0, $ms * 1000000); } if (isset($this->options['adjustPriority'])) { $this->adjustPriority($this->options['adjustPriority']); } $this->okToRun = true; try { while ($this->okToRun) { $this->memCheck(); $this->codeCheck(); $this->currentJob = $this->jqStore->next($this->options['queueName']); if ($this->currentJob) { try { $this->logJobStatus($this->currentJob, "Job checked out."); // attempt to un-serialize the job if ($this->currentJob->getJob() instanceof JQJob) { $this->logJobStatus($this->currentJob, $this->currentJob->description()); $result = $this->currentJob->run($this->currentJob); } else { $this->currentJob->markJobFailed("JQManagedJob.job is not a JQJob instance."); $result = "No JQJob found."; } if ($result === NULL) { $this->logJobStatus($this->currentJob, "Done!"); } else { $this->logJobStatus($this->currentJob, $result); } $this->currentJob = NULL; } catch (Exception $e) { if ($this->currentSignalNo === NULL) { throw $e; } // we only handle signals here // This block helps JQJobs minimize the incidence of jobs getting stuck in the "running" state // It is designed to catch exceptions from JQJob->run() trying to record a finished ActualJob->run() disposition to JQStore // although the job might've finished, we couldn't tell JQStore, thus the loop can't be closed // Therefore, we will gracefullyRetryCurrentJob() so that it can run again another day and close out the loop gracefully $result = $e->getMessage(); $this->logJobStatus($this->currentJob, "signal raised during job->run()", true); $this->gracefullyRetryCurrentJob($this->currentJob); $this->currentJob = NULL; // now that we've cleaned up, the run loop will gracefully exit } $this->jobsProcessed++; if ($this->options['exitAfterNJobs'] && $this->jobsProcessed >= $this->options['exitAfterNJobs']) { break; } } else { $this->log("No jobs available."); if ($this->options['exitIfNoJobs']) { $this->log("Exiting since exitIfNoJobs=true"); break; } else { $s = $this->options['wakeupEvery']; $ms = 0; if ($this->options['enableJitter']) { $ms = rand(0, 999); } $this->log("Sleeping for {$s}.{$ms} seconds..."); JQWorker::sleep($s, $ms * 1000000); } } } } catch (Exception $e) { if ($this->currentSignalNo === NULL) { throw $e; } // we only handle signals here // This block helps JQJobs minimize the incidence of jobs getting stuck in the "running" state // It is designed to catch jobs that have been checked out but not yet run when a signal fires // Therefore, we will gracefullyRetryCurrentJob() so that it can run again another day and close out the loop gracefully $result = $e->getMessage(); $this->log("signal raised during run()"); $this->gracefullyRetryCurrentJob($this->currentJob); exit(self::EXIT_CODE_SIGNAL); } $this->log("Stopping worker process on queue: " . ($this->options['queueName'] === NULL ? '(any)' : $this->options['queueName'])); }