public function doUpdate() { $job = new HTMLCacheUpdateJob($this->mTitle, array('table' => $this->mTable, 'recursive' => true) + Job::newRootJobParams("htmlCacheUpdate:{$this->mTable}:{$this->mTitle->getPrefixedText()}")); $count = $this->mTitle->getBacklinkCache()->getNumLinks($this->mTable, 100); if ($count >= 100) { // many backlinks JobQueueGroup::singleton()->lazyPush($job); } else { // few backlinks ($count might be off even if 0) $dbw = wfGetDB(DB_MASTER); $dbw->onTransactionIdle(function () use($job) { $job->run(); // just do the purge query now }); } }
public function doUpdate() { global $wgMaxBacklinksInvalidate; wfProfileIn(__METHOD__); $job = new HTMLCacheUpdateJob($this->mTitle, array('table' => $this->mTable) + Job::newRootJobParams("htmlCacheUpdate:{$this->mTable}:{$this->mTitle->getPrefixedText()}")); $count = $this->mTitle->getBacklinkCache()->getNumLinks($this->mTable, 200); if ($wgMaxBacklinksInvalidate !== false && $count > $wgMaxBacklinksInvalidate) { wfDebug("Skipped HTML cache invalidation of {$this->mTitle->getPrefixedText()}."); } elseif ($count >= 200) { // many backlinks JobQueueGroup::singleton()->push($job); JobQueueGroup::singleton()->deduplicateRootJob($job); } else { // few backlinks ($count might be off even if 0) $job->run(); // just do the purge query now } wfProfileOut(__METHOD__); }
/** * @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'); }
/** * Queue a RefreshLinks job for any table. * * @param Title $title Title to do job for * @param string $table Table to use (e.g. 'templatelinks') */ public static function queueRecursiveJobsForTable(Title $title, $table) { if ($title->getBacklinkCache()->hasLinks($table)) { $job = new RefreshLinksJob($title, array('table' => $table, 'recursive' => true) + Job::newRootJobParams("refreshlinks:{$table}:{$title->getPrefixedText()}")); JobQueueGroup::singleton()->push($job); } }
/** * @dataProvider provider_queueLists * @covers JobQueue */ public function testRootDeduplication($queue, $recycles, $desc) { $queue = $this->{$queue}; if (!$queue) { $this->markTestSkipped($desc); } $this->assertTrue($queue->isEmpty(), "Queue is empty ({$desc})"); $queue->flushCaches(); $this->assertEquals(0, $queue->getSize(), "Queue is empty ({$desc})"); $this->assertEquals(0, $queue->getAcquiredCount(), "Queue is empty ({$desc})"); $id = wfRandomString(32); $root1 = Job::newRootJobParams("nulljobspam:{$id}"); // task ID/timestamp for ($i = 0; $i < 5; ++$i) { $this->assertNull($queue->push($this->newJob(0, $root1)), "Push worked ({$desc})"); } $queue->deduplicateRootJob($this->newJob(0, $root1)); $root2 = $root1; # Add a second to UNIX epoch and format back to TS_MW $root2_ts = strtotime($root2['rootJobTimestamp']); $root2_ts++; $root2['rootJobTimestamp'] = wfTimestamp(TS_MW, $root2_ts); $this->assertNotEquals($root1['rootJobTimestamp'], $root2['rootJobTimestamp'], "Root job signatures have different timestamps."); for ($i = 0; $i < 5; ++$i) { $this->assertNull($queue->push($this->newJob(0, $root2)), "Push worked ({$desc})"); } $queue->deduplicateRootJob($this->newJob(0, $root2)); $this->assertFalse($queue->isEmpty(), "Queue is not empty ({$desc})"); $queue->flushCaches(); $this->assertEquals(10, $queue->getSize(), "Queue size is correct ({$desc})"); $this->assertEquals(0, $queue->getAcquiredCount(), "No jobs active ({$desc})"); $dupcount = 0; $jobs = []; do { $job = $queue->pop(); if ($job) { $jobs[] = $job; $queue->ack($job); } if ($job instanceof DuplicateJob) { ++$dupcount; } } while ($job); $this->assertEquals(10, count($jobs), "Correct number of jobs popped ({$desc})"); $this->assertEquals(5, $dupcount, "Correct number of duplicate jobs popped ({$desc})"); }
/** * @param Title $title Title to purge backlink pages from * @param string $table Backlink table name * @return HTMLCacheUpdateJob */ public static function newForBacklinks(Title $title, $table) { return new self($title, array('table' => $table, 'recursive' => true) + Job::newRootJobParams("htmlCacheUpdate:{$table}:{$title->getPrefixedText()}")); }
/** * Queue a RefreshLinks job for any table. * * @param Title $title Title to do job for * @param String $table Table to use (e.g. 'templatelinks') */ public static function queueRecursiveJobsForTable( Title $title, $table ) { wfProfileIn( __METHOD__ ); if ( $title->getBacklinkCache()->hasLinks( $table ) ) { $job = new RefreshLinksJob2( $title, array( 'table' => $table, ) + Job::newRootJobParams( // "overall" refresh links job info "refreshlinks:{$table}:{$title->getPrefixedText()}" ) ); JobQueueGroup::singleton()->push( $job ); JobQueueGroup::singleton()->deduplicateRootJob( $job ); } wfProfileOut( __METHOD__ ); }
function queueRecursiveJobs() { wfProfileIn(__METHOD__); if ($this->mTitle->getBacklinkCache()->hasLinks('templatelinks')) { $job = new RefreshLinksJob2($this->mTitle, array('table' => 'templatelinks') + Job::newRootJobParams("refreshlinks:templatelinks:{$this->mTitle->getPrefixedText()}")); JobQueueGroup::singleton()->push($job); JobQueueGroup::singleton()->deduplicateRootJob($job); } wfProfileOut(__METHOD__); }