function run()
 {
     global $wgUpdateRowsPerJob;
     // Job to update all (or a range of) backlink pages for a page
     if (!empty($this->params['recursive'])) {
         // Carry over information for de-duplication
         $extraParams = $this->getRootJobParams();
         // Avoid slave lag when fetching templates.
         // When the outermost job is run, we know that the caller that enqueued it must have
         // committed the relevant changes to the DB by now. At that point, record the master
         // position and pass it along as the job recursively breaks into smaller range jobs.
         // Hopefully, when leaf jobs are popped, the slaves will have reached that position.
         if (isset($this->params['masterPos'])) {
             $extraParams['masterPos'] = $this->params['masterPos'];
         } elseif (wfGetLB()->getServerCount() > 1) {
             $extraParams['masterPos'] = wfGetLB()->getMasterPos();
         } else {
             $extraParams['masterPos'] = false;
         }
         // Convert this into no more than $wgUpdateRowsPerJob RefreshLinks per-title
         // jobs and possibly a recursive RefreshLinks job for the rest of the backlinks
         $jobs = BacklinkJobUtils::partitionBacklinkJob($this, $wgUpdateRowsPerJob, 1, array('params' => $extraParams));
         JobQueueGroup::singleton()->push($jobs);
         // Job to update link tables for a set of titles
     } elseif (isset($this->params['pages'])) {
         foreach ($this->params['pages'] as $pageId => $nsAndKey) {
             list($ns, $dbKey) = $nsAndKey;
             $this->runForTitle(Title::makeTitleSafe($ns, $dbKey));
         }
         // Job to update link tables for a given title
     } else {
         $this->runForTitle($this->title);
     }
     return true;
 }
 function run()
 {
     global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery, $wgMaxBacklinksInvalidate;
     static $expected = array('recursive', 'pages');
     // new jobs have one of these
     $oldRangeJob = false;
     if (!array_intersect(array_keys($this->params), $expected)) {
         // B/C for older job params formats that lack these fields:
         // a) base jobs with just ("table") and b) range jobs with ("table","start","end")
         if (isset($this->params['start']) && isset($this->params['end'])) {
             $oldRangeJob = true;
         } else {
             $this->params['recursive'] = true;
             // base job
         }
     }
     // Job to purge all (or a range of) backlink pages for a page
     if (!empty($this->params['recursive'])) {
         // @TODO: try to use delayed jobs if possible?
         if (!isset($this->params['range']) && $wgMaxBacklinksInvalidate !== false) {
             $numRows = $this->title->getBacklinkCache()->getNumLinks($this->params['table'], $wgMaxBacklinksInvalidate);
             if ($numRows > $wgMaxBacklinksInvalidate) {
                 return true;
             }
         }
         // Convert this into no more than $wgUpdateRowsPerJob HTMLCacheUpdateJob per-title
         // jobs and possibly a recursive HTMLCacheUpdateJob job for the rest of the backlinks
         $jobs = BacklinkJobUtils::partitionBacklinkJob($this, $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery, array('params' => $this->getRootJobParams()));
         JobQueueGroup::singleton()->push($jobs);
         // Job to purge pages for for a set of titles
     } elseif (isset($this->params['pages'])) {
         $this->invalidateTitles($this->params['pages']);
         // B/C for job to purge a range of backlink pages for a given page
     } elseif ($oldRangeJob) {
         $titleArray = $this->title->getBacklinkCache()->getLinks($this->params['table'], $this->params['start'], $this->params['end']);
         $pages = array();
         // same format BacklinkJobUtils uses
         foreach ($titleArray as $tl) {
             $pages[$tl->getArticleId()] = array($tl->getNamespace(), $tl->getDbKey());
         }
         $jobs = array();
         foreach (array_chunk($pages, $wgUpdateRowsPerJob) as $pageChunk) {
             $jobs[] = new HTMLCacheUpdateJob($this->title, array('table' => $this->params['table'], 'pages' => $pageChunk) + $this->getRootJobParams());
         }
         JobQueueGroup::singleton()->push($jobs);
     }
     return true;
 }
 /**
  * @dataProvider provider_backlinks
  */
 public function testRefreshLinks($ns, $dbKey, $pages)
 {
     $title = Title::makeTitle($ns, $dbKey);
     foreach ($pages as $page) {
         list($bns, $bdbkey) = $page;
         $bpage = WikiPage::factory(Title::makeTitle($bns, $bdbkey));
         $content = ContentHandler::makeContent("[[{$title->getPrefixedText()}]]", $bpage->getTitle());
         $bpage->doEditContent($content, "test");
     }
     $title->getBacklinkCache()->clear();
     $this->assertEquals(20, $title->getBacklinkCache()->getNumLinks('pagelinks'), 'Correct number of backlinks');
     $job = new RefreshLinksJob($title, array('recursive' => true, 'table' => 'pagelinks') + Job::newRootJobParams("refreshlinks:pagelinks:{$title->getPrefixedText()}"));
     $extraParams = $job->getRootJobParams();
     $jobs = BacklinkJobUtils::partitionBacklinkJob($job, 9, 1, array('params' => $extraParams));
     $this->assertEquals(10, count($jobs), 'Correct number of sub-jobs');
     $this->assertEquals($pages[0], current($jobs[0]->params['pages']), 'First job is leaf job with proper title');
     $this->assertEquals($pages[8], current($jobs[8]->params['pages']), 'Last leaf job is leaf job with proper title');
     $this->assertEquals(true, isset($jobs[9]->params['recursive']), 'Last job is recursive sub-job');
     $this->assertEquals(true, $jobs[9]->params['recursive'], 'Last job is recursive sub-job');
     $this->assertEquals(true, is_array($jobs[9]->params['range']), 'Last job is recursive sub-job');
     $this->assertEquals($title->getPrefixedText(), $jobs[0]->getTitle()->getPrefixedText(), 'Base job title retainend in leaf job');
     $this->assertEquals($title->getPrefixedText(), $jobs[9]->getTitle()->getPrefixedText(), 'Base job title retainend recursive sub-job');
     $this->assertEquals($extraParams['rootJobSignature'], $jobs[0]->params['rootJobSignature'], 'Leaf job has root params');
     $this->assertEquals($extraParams['rootJobSignature'], $jobs[9]->params['rootJobSignature'], 'Recursive sub-job has root params');
     $jobs2 = BacklinkJobUtils::partitionBacklinkJob($jobs[9], 9, 1, array('params' => $extraParams));
     $this->assertEquals(10, count($jobs2), 'Correct number of sub-jobs');
     $this->assertEquals($pages[9], current($jobs2[0]->params['pages']), 'First job is leaf job with proper title');
     $this->assertEquals($pages[17], current($jobs2[8]->params['pages']), 'Last leaf job is leaf job with proper title');
     $this->assertEquals(true, isset($jobs2[9]->params['recursive']), 'Last job is recursive sub-job');
     $this->assertEquals(true, $jobs2[9]->params['recursive'], 'Last job is recursive sub-job');
     $this->assertEquals(true, is_array($jobs2[9]->params['range']), 'Last job is recursive sub-job');
     $this->assertEquals($extraParams['rootJobSignature'], $jobs2[0]->params['rootJobSignature'], 'Leaf job has root params');
     $this->assertEquals($extraParams['rootJobSignature'], $jobs2[9]->params['rootJobSignature'], 'Recursive sub-job has root params');
     $jobs3 = BacklinkJobUtils::partitionBacklinkJob($jobs2[9], 9, 1, array('params' => $extraParams));
     $this->assertEquals(2, count($jobs3), 'Correct number of sub-jobs');
     $this->assertEquals($pages[18], current($jobs3[0]->params['pages']), 'First job is leaf job with proper title');
     $this->assertEquals($extraParams['rootJobSignature'], $jobs3[0]->params['rootJobSignature'], 'Leaf job has root params');
     $this->assertEquals($pages[19], current($jobs3[1]->params['pages']), 'Last job is leaf job with proper title');
     $this->assertEquals($extraParams['rootJobSignature'], $jobs3[1]->params['rootJobSignature'], 'Last leaf job has root params');
 }
Esempio n. 4
0
 function run()
 {
     global $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery;
     if (isset($this->params['table']) && !isset($this->params['pages'])) {
         $this->params['recursive'] = true;
         // b/c; base job
     }
     // Job to purge all (or a range of) backlink pages for a page
     if (!empty($this->params['recursive'])) {
         // Convert this into no more than $wgUpdateRowsPerJob HTMLCacheUpdateJob per-title
         // jobs and possibly a recursive HTMLCacheUpdateJob job for the rest of the backlinks
         $jobs = BacklinkJobUtils::partitionBacklinkJob($this, $wgUpdateRowsPerJob, $wgUpdateRowsPerQuery, array('params' => $this->getRootJobParams()));
         JobQueueGroup::singleton()->push($jobs);
         // Job to purge pages for a set of titles
     } elseif (isset($this->params['pages'])) {
         $this->invalidateTitles($this->params['pages']);
         // Job to update a single title
     } else {
         $t = $this->title;
         $this->invalidateTitles(array($t->getArticleID() => array($t->getNamespace(), $t->getDBkey())));
     }
     return true;
 }
Esempio n. 5
0
 function run()
 {
     global $wgUpdateRowsPerJob;
     // Job to update all (or a range of) backlink pages for a page
     if (!empty($this->params['recursive'])) {
         // When the base job branches, wait for the replica DBs to catch up to the master.
         // From then on, we know that any template changes at the time the base job was
         // enqueued will be reflected in backlink page parses when the leaf jobs run.
         if (!isset($params['range'])) {
             try {
                 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                 $lbFactory->waitForReplication(['wiki' => wfWikiID(), 'timeout' => self::LAG_WAIT_TIMEOUT]);
             } catch (DBReplicationWaitError $e) {
                 // only try so hard
                 $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
                 $stats->increment('refreshlinks.lag_wait_failed');
             }
         }
         // Carry over information for de-duplication
         $extraParams = $this->getRootJobParams();
         $extraParams['triggeredRecursive'] = true;
         // Convert this into no more than $wgUpdateRowsPerJob RefreshLinks per-title
         // jobs and possibly a recursive RefreshLinks job for the rest of the backlinks
         $jobs = BacklinkJobUtils::partitionBacklinkJob($this, $wgUpdateRowsPerJob, 1, ['params' => $extraParams]);
         JobQueueGroup::singleton()->push($jobs);
         // Job to update link tables for a set of titles
     } elseif (isset($this->params['pages'])) {
         foreach ($this->params['pages'] as $pageId => $nsAndKey) {
             list($ns, $dbKey) = $nsAndKey;
             $this->runForTitle(Title::makeTitleSafe($ns, $dbKey));
         }
         // Job to update link tables for a given title
     } else {
         $this->runForTitle($this->title);
     }
     return true;
 }