* Job to update link tables for pages
*
* This job comes in a few variants:
- * - a) Recursive jobs to update links for backlink pages for a given title
- * - b) Jobs to update links for a set of titles (the job title is ignored)
- * - c) Jobs to update links for a single title (the job title)
+ * - a) Recursive jobs to update links for backlink pages for a given title.
+ * These jobs have have (recursive:true,table:<table>) set.
+ * - b) Jobs to update links for a set of pages (the job title is ignored).
+ * These jobs have have (pages:(<page ID>:(<namespace>,<title>),...) set.
+ * - c) Jobs to update links for a single page (the job title)
+ * These jobs need no extra fields set.
*
* @ingroup JobQueue
*/
class RefreshLinksJob extends Job {
- const VERSION = 1;
-
function __construct( $title, $params = '', $id = 0 ) {
parent::__construct( 'refreshLinks', $title, $params, $id );
- $this->params['version'] = self::VERSION;
// Base backlink update jobs and per-title update jobs can be de-duplicated.
// If template A changes twice before any jobs run, a clean queue will have:
// (A base, A base)
}
// Job to update all (or a range of) backlink pages for a page
- if ( isset( $this->params['recursive'] ) ) {
+ if ( !empty( $this->params['recursive'] ) ) {
// Carry over information for de-duplication
$extraParams = $this->getRootJobParams();
// Avoid slave lag when fetching templates.
}
// Job to update link tables for a given title
} else {
- $this->runForTitle( $this->mTitle );
+ $this->runForTitle( $this->title );
}
return true;
wfGetLB()->waitFor( $this->params['masterPos'] );
}
+ // Fetch the current revision...
$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
$content = $revision->getContentHandler()->makeEmptyContent();
}
- // Revision ID must be passed to the parser output to get revision variables correct
- $parserOutput = $content->getParserOutput( $title, $revision->getId(), null, false );
+ $parserOutput = false;
+ // 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 ( isset( $this->params['rootJobTimestamp'] ) ) {
+ $page = WikiPage::factory( $title );
+ $skewedTimestamp = wfTimestamp( TS_UNIX, $this->params['rootJobTimestamp'] ) + 5;
+ if ( $page->getTouched() > wfTimestamp( TS_MW, $skewedTimestamp ) ) {
+ $parserOptions = $page->makeParserOptions( 'canonical' );
+ $parserOutput = ParserCache::singleton()->getDirty( $page, $parserOptions );
+ if ( $parserOutput && $parserOutput->getCacheTime() <= $skewedTimestamp ) {
+ $parserOutput = false; // too stale
+ }
+ }
+ }
+ // Fetch the current revision and parse it if necessary...
+ if ( $parserOutput == false ) {
+ // Revision ID must be passed to the parser output to get revision variables correct
+ $parserOutput = $content->getParserOutput( $title, $revision->getId(), null, false );
+ }
$updates = $content->getSecondaryDataUpdates( $title, null, false, $parserOutput );
DataUpdate::runUpdates( $updates );