MediaWiki  1.23.0
ParserCache.php
Go to the documentation of this file.
1 <?php
28 class ParserCache {
29  private $mMemc;
35  public static function singleton() {
36  static $instance;
37  if ( !isset( $instance ) ) {
39  $instance = new ParserCache( $parserMemc );
40  }
41  return $instance;
42  }
43 
51  protected function __construct( $memCached ) {
52  if ( !$memCached ) {
53  throw new MWException( "Tried to create a ParserCache with an invalid memcached" );
54  }
55  $this->mMemc = $memCached;
56  }
57 
63  protected function getParserOutputKey( $article, $hash ) {
64  global $wgRequest;
65 
66  // idhash seem to mean 'page id' + 'rendering hash' (r3710)
67  $pageid = $article->getID();
68  $renderkey = (int)( $wgRequest->getVal( 'action' ) == 'render' );
69 
70  $key = wfMemcKey( 'pcache', 'idhash', "{$pageid}-{$renderkey}!{$hash}" );
71  return $key;
72  }
73 
78  protected function getOptionsKey( $article ) {
79  $pageid = $article->getID();
80  return wfMemcKey( 'pcache', 'idoptions', "{$pageid}" );
81  }
82 
97  function getETag( $article, $popts ) {
98  return 'W/"' . $this->getParserOutputKey( $article,
99  $popts->optionsHash( ParserOptions::legacyOptions(), $article->getTitle() ) ) .
100  "--" . $article->getTouched() . '"';
101  }
102 
109  public function getDirty( $article, $popts ) {
110  $value = $this->get( $article, $popts, true );
111  return is_object( $value ) ? $value : false;
112  }
113 
133  public function getKey( $article, $popts, $useOutdated = true ) {
134  global $wgCacheEpoch;
135 
136  if ( $popts instanceof User ) {
137  wfWarn( "Use of outdated prototype ParserCache::getKey( &\$article, &\$user )\n" );
138  $popts = ParserOptions::newFromUser( $popts );
139  }
140 
141  // Determine the options which affect this article
142  $optionsKey = $this->mMemc->get( $this->getOptionsKey( $article ) );
143  if ( $optionsKey != false ) {
144  if ( !$useOutdated && $optionsKey->expired( $article->getTouched() ) ) {
145  wfIncrStats( "pcache_miss_expired" );
146  $cacheTime = $optionsKey->getCacheTime();
147  wfDebug( "Parser options key expired, touched " . $article->getTouched() . ", epoch $wgCacheEpoch, cached $cacheTime\n" );
148  return false;
149  } elseif ( $optionsKey->isDifferentRevision( $article->getLatest() ) ) {
150  wfIncrStats( "pcache_miss_revid" );
151  $revId = $article->getLatest();
152  $cachedRevId = $optionsKey->getCacheRevisionId();
153  wfDebug( "ParserOutput key is for an old revision, latest $revId, cached $cachedRevId\n" );
154  return false;
155  }
156 
157  // $optionsKey->mUsedOptions is set by save() by calling ParserOutput::getUsedOptions()
158  $usedOptions = $optionsKey->mUsedOptions;
159  wfDebug( "Parser cache options found.\n" );
160  } else {
161  if ( !$useOutdated ) {
162  return false;
163  }
164  $usedOptions = ParserOptions::legacyOptions();
165  }
166 
167  return $this->getParserOutputKey( $article, $popts->optionsHash( $usedOptions, $article->getTitle() ) );
168  }
169 
180  public function get( $article, $popts, $useOutdated = false ) {
181  global $wgCacheEpoch;
182  wfProfileIn( __METHOD__ );
183 
184  $canCache = $article->checkTouched();
185  if ( !$canCache ) {
186  // It's a redirect now
187  wfProfileOut( __METHOD__ );
188  return false;
189  }
190 
191  $touched = $article->getTouched();
192 
193  $parserOutputKey = $this->getKey( $article, $popts, $useOutdated );
194  if ( $parserOutputKey === false ) {
195  wfIncrStats( 'pcache_miss_absent' );
196  wfProfileOut( __METHOD__ );
197  return false;
198  }
199 
200  $value = $this->mMemc->get( $parserOutputKey );
201  if ( !$value ) {
202  wfDebug( "ParserOutput cache miss.\n" );
203  wfIncrStats( "pcache_miss_absent" );
204  wfProfileOut( __METHOD__ );
205  return false;
206  }
207 
208  wfDebug( "ParserOutput cache found.\n" );
209 
210  // The edit section preference may not be the appropiate one in
211  // the ParserOutput, as we are not storing it in the parsercache
212  // key. Force it here. See bug 31445.
213  $value->setEditSectionTokens( $popts->getEditSection() );
214 
215  if ( !$useOutdated && $value->expired( $touched ) ) {
216  wfIncrStats( "pcache_miss_expired" );
217  $cacheTime = $value->getCacheTime();
218  wfDebug( "ParserOutput key expired, touched $touched, epoch $wgCacheEpoch, cached $cacheTime\n" );
219  $value = false;
220  } elseif ( $value->isDifferentRevision( $article->getLatest() ) ) {
221  wfIncrStats( "pcache_miss_revid" );
222  $revId = $article->getLatest();
223  $cachedRevId = $value->getCacheRevisionId();
224  wfDebug( "ParserOutput key is for an old revision, latest $revId, cached $cachedRevId\n" );
225  $value = false;
226  } else {
227  wfIncrStats( "pcache_hit" );
228  }
229 
230  wfProfileOut( __METHOD__ );
231  return $value;
232  }
233 
241  public function save( $parserOutput, $page, $popts, $cacheTime = null, $revId = null ) {
242  $expire = $parserOutput->getCacheExpiry();
243  if ( $expire > 0 ) {
244  $cacheTime = $cacheTime ?: wfTimestampNow();
245  if ( !$revId ) {
246  $revision = $page->getRevision();
247  $revId = $revision ? $revision->getId() : null;
248  }
249 
250  $optionsKey = new CacheTime;
251  $optionsKey->mUsedOptions = $parserOutput->getUsedOptions();
252  $optionsKey->updateCacheExpiry( $expire );
253 
254  $optionsKey->setCacheTime( $cacheTime );
255  $parserOutput->setCacheTime( $cacheTime );
256  $optionsKey->setCacheRevisionId( $revId );
257  $parserOutput->setCacheRevisionId( $revId );
258 
259  $optionsKey->setContainsOldMagic( $parserOutput->containsOldMagic() );
260 
261  $parserOutputKey = $this->getParserOutputKey( $page,
262  $popts->optionsHash( $optionsKey->mUsedOptions, $page->getTitle() ) );
263 
264  // Save the timestamp so that we don't have to load the revision row on view
265  $parserOutput->setTimestamp( $page->getTimestamp() );
266 
267  $msg = "Saved in parser cache with key $parserOutputKey" .
268  " and timestamp $cacheTime" .
269  " and revision id $revId" .
270  "\n";
271 
272  $parserOutput->mText .= "\n<!-- $msg -->\n";
273  wfDebug( $msg );
274 
275  // Save the parser output
276  $this->mMemc->set( $parserOutputKey, $parserOutput, $expire );
277 
278  // ...and its pointer
279  $this->mMemc->set( $this->getOptionsKey( $page ), $optionsKey, $expire );
280  } else {
281  wfDebug( "Parser output was marked as uncacheable and has not been saved.\n" );
282  }
283  }
284 }
ParserCache\$mMemc
$mMemc
Definition: ParserCache.php:29
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
CacheTime
Parser cache specific expiry check.
Definition: CacheTime.php:29
ParserCache\getKey
getKey( $article, $popts, $useOutdated=true)
Generates a key for caching the given article considering the given parser options.
Definition: ParserCache.php:133
ParserCache\__construct
__construct( $memCached)
Setup a cache pathway with a given back-end storage mechanism.
Definition: ParserCache.php:51
ParserCache\getETag
getETag( $article, $popts)
Provides an E-Tag suitable for the whole page.
Definition: ParserCache.php:97
wfProfileIn
wfProfileIn( $functionname)
Begin profiling of a function.
Definition: Profiler.php:33
ParserCache\getOptionsKey
getOptionsKey( $article)
Definition: ParserCache.php:78
$parserMemc
controlled by $wgMainCacheType * $parserMemc
Definition: memcached.txt:78
true
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition: hooks.txt:1530
MWException
MediaWiki exception.
Definition: MWException.php:26
ParserCache\save
save( $parserOutput, $page, $popts, $cacheTime=null, $revId=null)
Definition: ParserCache.php:241
wfMemcKey
wfMemcKey()
Get a cache key.
Definition: GlobalFunctions.php:3571
wfIncrStats
wfIncrStats( $key, $count=1)
Increment a statistics counter.
Definition: GlobalFunctions.php:1304
ParserCache\getDirty
getDirty( $article, $popts)
Retrieve the ParserOutput from ParserCache, even if it's outdated.
Definition: ParserCache.php:109
wfProfileOut
wfProfileOut( $functionname='missing')
Stop profiling of a function.
Definition: Profiler.php:46
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:2514
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:188
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:933
ParserCache\singleton
static singleton()
Get an instance of this object.
Definition: ParserCache.php:35
$value
$value
Definition: styleTest.css.php:45
$hash
return false to override stock group addition can be modified try getUserPermissionsErrors userCan checks are continued by internal code can override on output return false to not delete it return false to override the default password checks & $hash
Definition: hooks.txt:2697
ParserCache\getParserOutputKey
getParserOutputKey( $article, $hash)
Definition: ParserCache.php:63
ParserOptions\legacyOptions
static legacyOptions()
Returns the full array of options that would have been used by in 1.16.
Definition: ParserOptions.php:464
ParserCache
Definition: ParserCache.php:28
CacheTime\updateCacheExpiry
updateCacheExpiry( $seconds)
Sets the number of seconds after which this object should expire.
Definition: CacheTime.php:98
wfWarn
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
Definition: GlobalFunctions.php:1141
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:59
$article
Using a hook running we can avoid having all this option specific stuff in our mainline code Using the function array $article
Definition: hooks.txt:78
ParserOptions\newFromUser
static newFromUser( $user)
Get a ParserOptions object from a given user.
Definition: ParserOptions.php:375