示例#1
0
 /**
  * @param Job $job
  * @param LBFactory $lbFactory
  * @param StatsdDataFactory $stats
  * @param float $popTime
  * @return array Map of status/error/timeMs
  */
 private function executeJob(Job $job, LBFactory $lbFactory, $stats, $popTime)
 {
     $jType = $job->getType();
     $msg = $job->toString() . " STARTING";
     $this->logger->debug($msg);
     $this->debugCallback($msg);
     // Run the job...
     $rssStart = $this->getMaxRssKb();
     $jobStartTime = microtime(true);
     try {
         $fnameTrxOwner = get_class($job) . '::run';
         // give run() outer scope
         $lbFactory->beginMasterChanges($fnameTrxOwner);
         $status = $job->run();
         $error = $job->getLastError();
         $this->commitMasterChanges($lbFactory, $job, $fnameTrxOwner);
         // Run any deferred update tasks; doUpdates() manages transactions itself
         DeferredUpdates::doUpdates();
     } catch (Exception $e) {
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         $status = false;
         $error = get_class($e) . ': ' . $e->getMessage();
     }
     // Always attempt to call teardown() even if Job throws exception.
     try {
         $job->teardown($status);
     } catch (Exception $e) {
         MWExceptionHandler::logException($e);
     }
     // Commit all outstanding connections that are in a transaction
     // to get a fresh repeatable read snapshot on every connection.
     // Note that jobs are still responsible for handling replica DB lag.
     $lbFactory->flushReplicaSnapshots(__METHOD__);
     // Clear out title cache data from prior snapshots
     MediaWikiServices::getInstance()->getLinkCache()->clear();
     $timeMs = intval((microtime(true) - $jobStartTime) * 1000);
     $rssEnd = $this->getMaxRssKb();
     // Record how long jobs wait before getting popped
     $readyTs = $job->getReadyTimestamp();
     if ($readyTs) {
         $pickupDelay = max(0, $popTime - $readyTs);
         $stats->timing('jobqueue.pickup_delay.all', 1000 * $pickupDelay);
         $stats->timing("jobqueue.pickup_delay.{$jType}", 1000 * $pickupDelay);
     }
     // Record root job age for jobs being run
     $rootTimestamp = $job->getRootJobParams()['rootJobTimestamp'];
     if ($rootTimestamp) {
         $age = max(0, $popTime - wfTimestamp(TS_UNIX, $rootTimestamp));
         $stats->timing("jobqueue.pickup_root_age.{$jType}", 1000 * $age);
     }
     // Track the execution time for jobs
     $stats->timing("jobqueue.run.{$jType}", $timeMs);
     // Track RSS increases for jobs (in case of memory leaks)
     if ($rssStart && $rssEnd) {
         $stats->updateCount("jobqueue.rss_delta.{$jType}", $rssEnd - $rssStart);
     }
     if ($status === false) {
         $msg = $job->toString() . " t={$timeMs} error={$error}";
         $this->logger->error($msg);
         $this->debugCallback($msg);
     } else {
         $msg = $job->toString() . " t={$timeMs} good";
         $this->logger->info($msg);
         $this->debugCallback($msg);
     }
     return ['status' => $status, 'error' => $error, 'timeMs' => $timeMs];
 }