diff options
Diffstat (limited to 'includes/jobqueue/jobs/RefreshLinksJob.php')
-rw-r--r-- | includes/jobqueue/jobs/RefreshLinksJob.php | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/includes/jobqueue/jobs/RefreshLinksJob.php b/includes/jobqueue/jobs/RefreshLinksJob.php index 1252b0b5..935d2fb1 100644 --- a/includes/jobqueue/jobs/RefreshLinksJob.php +++ b/includes/jobqueue/jobs/RefreshLinksJob.php @@ -37,7 +37,9 @@ class RefreshLinksJob extends Job { const PARSE_THRESHOLD_SEC = 1.0; - function __construct( $title, $params = '' ) { + const CLOCK_FUDGE = 10; + + function __construct( Title $title, array $params ) { parent::__construct( 'refreshLinks', $title, $params ); // A separate type is used just for cascade-protected backlinks if ( !empty( $this->params['prioritize'] ) ) { @@ -109,9 +111,6 @@ class RefreshLinksJob extends Job { * @return bool */ protected function runForTitle( Title $title = null ) { - $linkCache = LinkCache::singleton(); - $linkCache->clear(); - if ( is_null( $title ) ) { $this->setLastError( "refreshLinks: Invalid title" ); return false; @@ -124,14 +123,18 @@ class RefreshLinksJob extends Job { wfGetLB()->waitFor( $this->params['masterPos'] ); } - $page = WikiPage::factory( $title ); + // Clear out title cache data from prior job transaction snapshots + $linkCache = LinkCache::singleton(); + $linkCache->clear(); - // Fetch the current revision... + // Fetch the current page and revision... + $page = WikiPage::factory( $title ); $revision = Revision::newFromTitle( $title, false, Revision::READ_NORMAL ); if ( !$revision ) { $this->setLastError( "refreshLinks: Article not found {$title->getPrefixedDBkey()}" ); return false; // XXX: what if it was just deleted? } + $content = $revision->getContent( Revision::RAW ); if ( !$content ) { // If there is no content, pretend the content is empty @@ -140,34 +143,50 @@ class RefreshLinksJob extends Job { $parserOutput = false; $parserOptions = $page->makeParserOptions( 'canonical' ); - // If page_touched changed after this root job (with a good slave lag skew factor), - // then it is likely that any views of the pages already resulted in re-parses which - // are now in cache. This can be reused to avoid expensive parsing in some cases. + // If page_touched changed after this root job, then it is likely that + // any views of the pages already resulted in re-parses which are now in + // cache. The cache can be reused to avoid expensive parsing in some cases. if ( isset( $this->params['rootJobTimestamp'] ) ) { - $skewedTimestamp = wfTimestamp( TS_UNIX, $this->params['rootJobTimestamp'] ) + 5; - if ( $page->getLinksTimestamp() > wfTimestamp( TS_MW, $skewedTimestamp ) ) { + $opportunistic = !empty( $this->params['isOpportunistic'] ); + + $skewedTimestamp = $this->params['rootJobTimestamp']; + if ( $opportunistic ) { + // Neither clock skew nor DB snapshot/slave lag matter much for such + // updates; focus on reusing the (often recently updated) cache + } else { + // For transclusion updates, the template changes must be reflected + $skewedTimestamp = wfTimestamp( TS_MW, + wfTimestamp( TS_UNIX, $skewedTimestamp ) + self::CLOCK_FUDGE + ); + } + + if ( $page->getLinksTimestamp() > $skewedTimestamp ) { // Something already updated the backlinks since this job was made return true; } - if ( $page->getTouched() > wfTimestamp( TS_MW, $skewedTimestamp ) ) { + + if ( $page->getTouched() >= $skewedTimestamp || $opportunistic ) { + // Something bumped page_touched since this job was made + // or the cache is otherwise suspected to be up-to-date $parserOutput = ParserCache::singleton()->getDirty( $page, $parserOptions ); - if ( $parserOutput && $parserOutput->getCacheTime() <= $skewedTimestamp ) { + if ( $parserOutput && $parserOutput->getCacheTime() < $skewedTimestamp ) { $parserOutput = false; // too stale } } } + // Fetch the current revision and parse it if necessary... if ( $parserOutput == false ) { $start = microtime( true ); // Revision ID must be passed to the parser output to get revision variables correct $parserOutput = $content->getParserOutput( $title, $revision->getId(), $parserOptions, false ); - $ellapsed = microtime( true ) - $start; + $elapsed = microtime( true ) - $start; // If it took a long time to render, then save this back to the cache to avoid // wasted CPU by other apaches or job runners. We don't want to always save to // cache as this can cause high cache I/O and LRU churn when a template changes. - if ( $ellapsed >= self::PARSE_THRESHOLD_SEC - && $page->isParserCacheUsed( $parserOptions, $revision->getId() ) + if ( $elapsed >= self::PARSE_THRESHOLD_SEC + && $page->shouldCheckParserCache( $parserOptions, $revision->getId() ) && $parserOutput->isCacheable() ) { $ctime = wfTimestamp( TS_MW, (int)$start ); // cache time |