From 36c68af11935af5b2352b2869590d6c7f35ecc67 Mon Sep 17 00:00:00 2001 From: Daniel Kinzler Date: Tue, 1 Jun 2010 14:28:51 +0000 Subject: [PATCH] allow parser/extensions to control for how long a ParserOutput gets cached. Introduced updateCacheExpiry(), Cleaned up use of getCacheTime() for marking uncacheable objects. --- includes/Article.php | 4 +-- includes/OutputPage.php | 4 +-- includes/parser/Parser.php | 3 +- includes/parser/ParserCache.php | 10 ++---- includes/parser/ParserOutput.php | 60 ++++++++++++++++++++++++++++++-- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 1eee511e53..778c051b35 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -4457,7 +4457,7 @@ class Article { $this->mTitle->getPrefixedDBkey() ) ); } - if ( $wgEnableParserCache && $cache && $this && $this->mParserOutput->getCacheTime() != -1 ) { + if ( $wgEnableParserCache && $cache && $this && !$this->mParserOutput->isCacheable() ) { $parserCache = ParserCache::singleton(); $parserCache->save( $this->mParserOutput, $this, $parserOptions ); } @@ -4465,7 +4465,7 @@ class Article { // Make sure file cache is not used on uncacheable content. // Output that has magic words in it can still use the parser cache // (if enabled), though it will generally expire sooner. - if ( $this->mParserOutput->getCacheTime() == -1 || $this->mParserOutput->containsOldMagic() ) { + if ( !$this->mParserOutput->isCacheable() || $this->mParserOutput->containsOldMagic() ) { $wgUseFileCache = false; } diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 680b4c6f8c..ed469782b3 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -1050,7 +1050,7 @@ class OutputPage { $popts, true, true, $this->mRevisionId ); $popts->setTidy( false ); - if ( $cache && $article && $parserOutput->getCacheTime() != -1 ) { + if ( $cache && $article && !$parserOutput->isCacheable() ) { $parserCache = ParserCache::singleton(); $parserCache->save( $parserOutput, $article, $popts ); } @@ -1078,7 +1078,7 @@ class OutputPage { $this->mHideNewSectionLink = $parserOutput->getHideNewSection(); $this->mParseWarnings = $parserOutput->getWarnings(); - if ( $parserOutput->getCacheTime() == -1 ) { + if ( !$parserOutput->isCacheable() ) { $this->enableClientCache( false ); } $this->mNoGallery = $parserOutput->getNoGallery(); diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 63b3b41f49..a54b8882ac 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -4787,7 +4787,8 @@ class Parser { */ function disableCache() { wfDebug( "Parser output marked as uncacheable.\n" ); - $this->mOutput->mCacheTime = -1; + $this->mOutput->setCacheTime( -1 ); // old style, for compatibility + $this->mOutput->setCacheExpiry( 0 ); // new style, for consistency } /**#@+ diff --git a/includes/parser/ParserCache.php b/includes/parser/ParserCache.php index af596633dd..7ef1c387bb 100644 --- a/includes/parser/ParserCache.php +++ b/includes/parser/ParserCache.php @@ -96,11 +96,10 @@ class ParserCache { } function save( $parserOutput, $article, $popts ){ - global $wgParserCacheExpireTime; $key = $this->getKey( $article, $popts ); + $expire = $parserOutput->getCacheExpiry(); - if( $parserOutput->getCacheTime() != -1 ) { - + if( $expire > 0 ) { $now = wfTimestampNow(); $parserOutput->setCacheTime( $now ); @@ -110,11 +109,6 @@ class ParserCache { $parserOutput->mText .= "\n\n"; wfDebug( "Saved in parser cache with key $key and timestamp $now\n" ); - if( $parserOutput->containsOldMagic() ){ - $expire = 3600; # 1 hour - } else { - $expire = $wgParserCacheExpireTime; - } $this->mMemc->set( $key, $parserOutput, $expire ); } else { diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index bc805d8dc0..1f390a26e8 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -11,6 +11,7 @@ class ParserOutput $mContainsOldMagic, # Boolean variable indicating if the input contained variables like {{CURRENTDAY}} $mTitleText, # title text of the chosen language variant $mCacheTime = '', # Time when this object was generated, or -1 for uncacheable. Used in ParserCache. + $mCacheExpiry = null, # Seconds after which the object should expire, use 0 for uncachable. Used in ParserCache. $mVersion = Parser::VERSION, # Compatibility check $mLinks = array(), # 2-D map of NS/DBK to ID for the links in the document. ID=zero for broken. $mTemplates = array(), # 2-D map of NS/DBK to ID for the template references. ID=zero for broken. @@ -64,12 +65,66 @@ class ParserOutput function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); } function setCategoryLinks( $cl ) { return wfSetVar( $this->mCategories, $cl ); } function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); } - function setCacheTime( $t ) { return wfSetVar( $this->mCacheTime, $t ); } + + /** setCacheTime() sets the timestamp expressing when the page has been rendered. + * This doesn not control expiry, see updateCacheExpiry() for that! + */ + function setCacheTime( $t ) { return wfSetVar( $this->mCacheTime, $t ); } function setTitleText( $t ) { return wfSetVar( $this->mTitleText, $t ); } function setSections( $toc ) { return wfSetVar( $this->mSections, $toc ); } function setIndexPolicy( $policy ) { return wfSetVar( $this->mIndexPolicy, $policy ); } function setTOCHTML( $tochtml ) { return wfSetVar( $this->mTOCHTML, $tochtml ); } + + /** Sets the number of seconds after which this object should expire. + * This value is used with the ParserCache. + * If called with a value greater than the value provided at any previous call, + * the new call has no effect. The value returned by getCacheExpiry is smaller + * or equal to the smallest number that was provided as an argument to + * updateCacheExpiry(). + */ + function updateCacheExpiry( $seconds ) { + $seconds = (int)$seconds; + + if ( $this->mCacheExpiry === null || $this->mCacheExpiry > $seconds ) + $this->mCacheExpiry = $seconds; + + // hack: set old-style marker for uncacheable entries. + if ( $this->mCacheExpiry !== null && $this->mCacheExpiry <= 0 ) + $this->mCacheTime = -1; + } + + /** Returns the number of seconds after which this object should expire. + * This method is used by ParserCache to determine how long the ParserOutput can be cached. + * The timestamp of expiry can be calculated by adding getCacheExpiry() to getCacheTime(). + * The value returned by getCacheExpiry is smaller or equal to the smallest number + * that was provided to a call of updateCacheExpiry(), and smaller or equal to the + * value of $wgParserCacheExpireTime. + */ + function getCacheExpiry() { + global $wgParserCacheExpireTime; + + if ( $this->mCacheTime < 0 ) return 0; // old-style marker for "not cachable" + + $expire = $this->mCacheExpiry; + + if ( $expire === null ) + $expire = $wgParserCacheExpireTime; + else + $expire = min( $expire, $wgParserCacheExpireTime ); + + if( $this->containsOldMagic() ) { //compatibility hack + $expire = min( $expire, 3600 ); # 1 hour + } + + if ( $expire <= 0 ) return 0; // not cachable + else return $expire; + } + + function isCacheable() { + return $this->getCacheExpiry() > 0; + } + function addCategory( $c, $sort ) { $this->mCategories[$c] = $sort; } function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; } function addWarning( $s ) { $this->mWarnings[$s] = 1; } @@ -174,9 +229,10 @@ class ParserOutput */ public function expired( $touched ) { global $wgCacheEpoch; - return $this->getCacheTime() == -1 || // parser says it's uncacheable + return !$this->isCacheable() || // parser says it's uncacheable $this->getCacheTime() < $touched || $this->getCacheTime() <= $wgCacheEpoch || + $this->getCacheTime() < wfTimestamp( TS_MW, time() - $this->getCacheExpiry() ) || // expiry period has passed !isset( $this->mVersion ) || version_compare( $this->mVersion, Parser::VERSION, "lt" ); } -- 2.20.1