https://www.mediawiki.org/wiki/Special:Code/MediaWiki/112773
Revision: 112773 Author: aaron Date: 2012-03-01 05:27:49 +0000 (Thu, 01 Mar 2012) Log Message: ----------- (bug 33353) Sanity check template/file versions to decide if non-current version inclusion cache is outdated. For the current version, this still relies on page_touched. Also improved cache use a bit for when the revision author is an anon. Modified Paths: -------------- trunk/extensions/FlaggedRevs/backend/FRInclusionCache.php Modified: trunk/extensions/FlaggedRevs/backend/FRInclusionCache.php =================================================================== --- trunk/extensions/FlaggedRevs/backend/FRInclusionCache.php 2012-03-01 05:00:50 UTC (rev 112772) +++ trunk/extensions/FlaggedRevs/backend/FRInclusionCache.php 2012-03-01 05:27:49 UTC (rev 112773) @@ -19,55 +19,98 @@ ) { global $wgParser, $wgMemc; wfProfileIn( __METHOD__ ); - $versions = false; + $key = self::getCacheKey( $article->getTitle(), $rev->getId() ); - if ( $regen !== 'regen' ) { // check cache + if ( $regen === 'regen' ) { + $versions = false; // skip cache + } elseif ( $rev->isCurrent() ) { + // Check cache entry against page_touched + $versions = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article ); + } else { + // Old revs won't always be invalidated with template/file changes. + // Also, we don't care if page_touched changed due to a direct edit. $versions = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article, 'allowStale' ); + if ( is_array( $versions ) ) { // entry exists + // Sanity check that the cache is reasonably up to date + list( $templates, $files ) = $versions; + if ( self::templatesStale( $templates ) || self::filesStale( $files ) ) { + $versions = false; // no good + } + } } + if ( !is_array( $versions ) ) { // cache miss $pOut = false; if ( $rev->isCurrent() ) { $parserCache = ParserCache::singleton(); - # Try current version parser cache (as anon)... + # Try current version parser cache for this user... $pOut = $parserCache->get( $article, $article->makeParserOptions( $user ) ); - if ( $pOut == false && $rev->getUser() ) { // try the user who saved the change - $author = User::newFromId( $rev->getUser() ); - $pOut = $parserCache->get( $article, $article->makeParserOptions( $author ) ); + if ( $pOut == false ) { + # Try current version parser cache for the revision author... + $optsUser = $rev->getUser() + ? User::newFromId( $rev->getUser() ) + : 'canonical'; + $pOut = $parserCache->get( $article, $article->makeParserOptions( $optsUser ) ); } } // ParserOutput::mImageTimeKeys wasn't always there if ( $pOut == false || !FlaggedRevs::parserOutputIsVersioned( $pOut ) ) { - $title = $article->getTitle(); - $pOpts = ParserOptions::newFromUser( $user ); // Note: tidy off $pOut = $wgParser->parse( - $rev->getText(), $title, $pOpts, true, true, $rev->getId() ); + $rev->getText(), + $article->getTitle(), + ParserOptions::newFromUser( $user ), // Note: tidy off + true, + true, + $rev->getId() + ); } # Get the template/file versions used... $versions = array( $pOut->getTemplateIds(), $pOut->getFileSearchOptions() ); # Save to cache (check cache expiry for dynamic elements)... $data = FlaggedRevs::makeMemcObj( $versions ); $wgMemc->set( $key, $data, $pOut->getCacheExpiry() ); - } else { - $tVersions =& $versions[0]; // templates - # Do a link batch query for page_latest... - $lb = new LinkBatch(); - foreach ( $tVersions as $ns => $tmps ) { - foreach ( $tmps as $dbKey => $revIdDraft ) { - $lb->add( $ns, $dbKey ); + } + + wfProfileOut( __METHOD__ ); + return $versions; + } + + protected static function templatesStale( array $tVersions ) { + # Do a link batch query for page_latest... + $lb = new LinkBatch(); + foreach ( $tVersions as $ns => $tmps ) { + foreach ( $tmps as $dbKey => $revIdDraft ) { + $lb->add( $ns, $dbKey ); + } + } + $lb->execute(); + # Check if any of these templates have a newer version + foreach ( $tVersions as $ns => $tmps ) { + foreach ( $tmps as $dbKey => $revIdDraft ) { + $title = Title::makeTitle( $ns, $dbKey ); + if ( $revIdDraft != $title->getLatestRevID() ) { + return true; } } - $lb->execute(); - # Update array with the current page_latest values. - # This kludge is there since $newTemplates (thus $revIdDraft) is cached. - foreach ( $tVersions as $ns => &$tmps ) { - foreach ( $tmps as $dbKey => &$revIdDraft ) { - $title = Title::makeTitle( $ns, $dbKey ); - $revIdDraft = (int)$title->getLatestRevID(); + } + return false; + } + + protected static function filesStale( array $fVersions ) { + # Check if any of these files have a newer version + foreach ( $fVersions as $name => $timeAndSHA1 ) { + $file = wfFindFile( $name ); + if ( $file ) { + if ( $file->getTimestamp() != $timeAndSHA1['time'] ) { + return true; } + } else { + if ( $timeAndSHA1['time'] ) { + return true; + } } } - wfProfileOut( __METHOD__ ); - return $versions; + return false; } /** _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs