28use InvalidArgumentException;
34use Psr\Log\LoggerInterface;
91 LoggerInterface $logger
95 $this->cacheExpiry = $cacheExpiry;
96 $this->cacheEpoch = $cacheEpoch;
97 $this->jsonCodec = $jsonCodec;
98 $this->stats = $stats;
99 $this->logger = $logger;
106 private function incrementStats(
RevisionRecord $revision,
string $metricSuffix ) {
107 $metricSuffix = str_replace(
'.',
'_', $metricSuffix );
108 $this->stats->increment(
"RevisionOutputCache.{$this->name}.{$metricSuffix}" );
132 array $usedOptions =
null
136 $revId = $revision->
getId();
139 throw new InvalidArgumentException(
"Revision must have an id number" );
142 return $this->cache->makeKey( $this->name, $revId, $hash );
165 array $usedOptions =
null
170 $revId = (string)$revision->
getId();
172 return $this->cache->makeKey( $this->name, $revId, $hash );
185 if ( $this->cacheExpiry <= 0 ) {
190 if ( !$parserOptions->isSafeToCache() ) {
191 $this->incrementStats( $revision,
'miss.unsafe' );
195 $cacheKey = $this->makeParserOutputKey( $revision, $parserOptions );
196 $json = $this->cache->get( $cacheKey );
198 if ( $json ===
false ) {
199 $this->incrementStats( $revision,
'miss.absent' );
203 $output = $this->restoreFromJson( $json, $cacheKey, ParserOutput::class );
204 if ( $output ===
null ) {
205 $this->incrementStats( $revision,
'miss.unserialize' );
209 $cacheTime = (int)MWTimestamp::convert( TS_UNIX, $output->getCacheTime() );
210 $expiryTime = (int)MWTimestamp::convert( TS_UNIX, $this->cacheEpoch );
211 $expiryTime = max( $expiryTime, (
int)MWTimestamp::now( TS_UNIX ) - $this->cacheExpiry );
213 if ( $cacheTime < $expiryTime ) {
214 $this->incrementStats( $revision,
'miss.expired' );
218 $this->logger->debug(
'old-revision cache hit' );
219 $this->incrementStats( $revision,
'hit' );
233 string $cacheTime =
null
236 throw new InvalidArgumentException(
'Attempt to cache a ParserOutput with no text set!' );
239 if ( $this->cacheExpiry <= 0 ) {
244 $cacheKey = $this->makeParserOutputKey( $revision, $parserOptions );
252 $msg =
"Saved in RevisionOutputCache with key $cacheKey" .
253 " and timestamp $cacheTime" .
254 " and revision id {$revision->getId()}.";
262 if ( $expiry <= 0 ) {
263 $this->incrementStats( $revision,
'save.uncacheable' );
268 $this->incrementStats( $revision,
'save.unsafe' );
272 $json = $this->encodeAsJson( $output, $cacheKey );
273 if ( $json ===
null ) {
274 $this->incrementStats( $revision,
'save.nonserializable' );
278 $this->cache->set( $cacheKey, $json, $expiry );
279 $this->incrementStats( $revision,
'save.success' );
288 private function restoreFromJson(
string $jsonData,
string $key,
string $expectedClass ) {
291 $obj = $this->jsonCodec->unserialize( $jsonData, $expectedClass );
293 }
catch ( InvalidArgumentException $e ) {
294 $this->logger->error(
'Unable to unserialize JSON', [
295 'name' => $this->name,
297 'message' => $e->getMessage()
308 private function encodeAsJson(
CacheTime $obj,
string $key ) {
310 return $this->jsonCodec->serialize( $obj );
311 }
catch ( InvalidArgumentException $e ) {
312 $this->logger->error(
'Unable to serialize JSON', [
313 'name' => $this->name,
315 'message' => $e->getMessage(),
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Parser cache specific expiry check.
updateCacheExpiry( $seconds)
Sets the number of seconds after which this object should expire.
setCacheTime( $t)
setCacheTime() sets the timestamp expressing when the page has been rendered.
getCacheExpiry()
Returns the number of seconds after which this object should expire.
Library for creating and parsing MW-style timestamps.
Set options of the Parser.
isSafeToCache(array $usedOptions=null)
Test whether these options are safe to cache.
optionsHash( $forOptions, $title=null)
Generate a hash string with the values set on these ParserOptions for the keys given in the array.
hasText()
Returns true if text was passed to the constructor, or set using setText().
addCacheMessage(string $msg)
Adds a comment notice about cache state to the text of the page.
setTimestamp( $timestamp)
Multi-datacenter aware caching interface.
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.