Turn ParserCache into a service, deprecate $parserMemc
authorKunal Mehta <legoktm@member.fsf.org>
Tue, 30 May 2017 00:10:16 +0000 (17:10 -0700)
committerKunal Mehta <legoktm@member.fsf.org>
Thu, 6 Jul 2017 02:56:49 +0000 (19:56 -0700)
ParserCache is already a singleton, making it a good candidate for a
service. $parserMemc is an odd global (it lacks the "wg" prefix) and is
ripe for deprecation.

The following are now deprecated:
* $parserMemc global
* ParserCache::singleton()
* wfGetParserCacheStorage()

A ParserCache::getCacheStorage() method was added for cases where direct
access to the underlying BagOStuff object is necessary.

Usage of $parserMemc will emit deprecation warnings through the
DeprecatedGlobal class mechanism. All usage in core was migrated.

Also take this opportunity to inject the $wgCacheEpoch global value into
ParserCache. This will require an update to the FlaggedRevs extension.

Change-Id: I2ac7afff0d8522214329248c3d1cdccd0f72bbd4

RELEASE-NOTES-1.30
includes/GlobalFunctions.php
includes/MediaWikiServices.php
includes/ServiceWiring.php
includes/Setup.php
includes/parser/ParserCache.php
maintenance/purgeParserCache.php
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/suites/UploadFromUrlTestSuite.php

index c95e799..7ceb327 100644 (file)
@@ -129,6 +129,10 @@ changes to languages because of Phabricator reports.
 * Article::viewRedirect() is deprecated.
 * DeprecatedGlobal no longer supports passing in a direct value, it requires a
   callable factory function or a class name.
+* The $parserMemc global, wfGetParserCacheStorage(), and ParserCache::singleton()
+  are all deprecated. The main ParserCache instance should be obtained from
+  MediaWikiServices instead. Access to the underlying BagOStuff is possible
+  through the new ParserCache::getCacheStorage() method.
 
 == Compatibility ==
 MediaWiki 1.30 requires PHP 5.5.9 or later. There is experimental support for
index 089ed81..92cb8d8 100644 (file)
@@ -3461,6 +3461,7 @@ function wfGetMessageCacheStorage() {
 /**
  * Get the cache object used by the parser cache
  *
+ * @deprecated since 1.30, use MediaWikiServices::getParserCache()->getCacheStorage()
  * @return BagOStuff
  */
 function wfGetParserCacheStorage() {
index 6161ee7..ea0ec15 100644 (file)
@@ -23,6 +23,7 @@ use MWException;
 use MimeAnalyzer;
 use ObjectCache;
 use Parser;
+use ParserCache;
 use ProxyLookup;
 use SearchEngine;
 use SearchEngineConfig;
@@ -573,6 +574,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'Parser' );
        }
 
+       /**
+        * @since 1.30
+        * @return ParserCache
+        */
+       public function getParserCache() {
+               return $this->getService( 'ParserCache' );
+       }
+
        /**
         * @since 1.28
         * @return GenderCache
index 2dfcc42..e1244e7 100644 (file)
@@ -287,7 +287,18 @@ return [
                return ObjectFactory::constructClassInstance( $conf['class'], [ $conf ] );
        },
 
-       'LinkCache' => function ( MediaWikiServices $services ) {
+       'ParserCache' => function( MediaWikiServices $services ) {
+               $config = $services->getMainConfig();
+               $cache = ObjectCache::getInstance( $config->get( 'ParserCacheType' ) );
+               wfDebugLog( 'caches', 'parser: ' . get_class( $cache ) );
+
+               return new ParserCache(
+                       $cache,
+                       $config->get( 'CacheEpoch' )
+               );
+       },
+
+       'LinkCache' => function( MediaWikiServices $services ) {
                return new LinkCache(
                        $services->getTitleFormatter(),
                        $services->getMainWANObjectCache()
index 5795517..ac00fab 100644 (file)
@@ -683,14 +683,19 @@ $ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' );
 
 $wgMemc = wfGetMainCache();
 $messageMemc = wfGetMessageCacheStorage();
-$parserMemc = wfGetParserCacheStorage();
+
+/**
+ * @deprecated since 1.30
+ */
+$parserMemc = new DeprecatedGlobal( 'parserMemc', function() {
+       return MediaWikiServices::getInstance()->getParserCache()->getCacheStorage();
+}, '1.30' );
 
 wfDebugLog( 'caches',
        'cluster: ' . get_class( $wgMemc ) .
        ', WAN: ' . ( $wgMainWANCache === CACHE_NONE ? 'CACHE_NONE' : $wgMainWANCache ) .
        ', stash: ' . $wgMainStash .
        ', message: ' . get_class( $messageMemc ) .
-       ', parser: ' . get_class( $parserMemc ) .
        ', session: ' . get_class( ObjectCache::getInstance( $wgSessionCacheType ) )
 );
 
index 3b84c4b..c680129 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Cache Parser
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @ingroup Cache Parser
  * @todo document
@@ -48,18 +50,21 @@ class ParserCache {
 
        /** @var BagOStuff */
        private $mMemc;
+
+       /**
+        * Anything cached prior to this is invalidated
+        *
+        * @var string
+        */
+       private $cacheEpoch;
        /**
         * Get an instance of this object
         *
+        * @deprecated since 1.30, use MediaWikiServices instead
         * @return ParserCache
         */
        public static function singleton() {
-               static $instance;
-               if ( !isset( $instance ) ) {
-                       global $parserMemc;
-                       $instance = new ParserCache( $parserMemc );
-               }
-               return $instance;
+               return MediaWikiServices::getInstance()->getParserCache();
        }
 
        /**
@@ -68,11 +73,13 @@ class ParserCache {
         * This class use an invalidation strategy that is compatible with
         * MultiWriteBagOStuff in async replication mode.
         *
-        * @param BagOStuff $memCached
+        * @param BagOStuff $cache
+        * @param string $cacheEpoch Anything before this timestamp is invalidated
         * @throws MWException
         */
-       protected function __construct( BagOStuff $memCached ) {
-               $this->mMemc = $memCached;
+       public function __construct( BagOStuff $cache, $cacheEpoch = '20030516000000' ) {
+               $this->mMemc = $cache;
+               $this->cacheEpoch = $cacheEpoch;
        }
 
        /**
@@ -159,8 +166,6 @@ class ParserCache {
         * @since 1.30 Changed $useOutdated to an int and added the non-boolean values
         */
        public function getKey( $article, $popts, $useOutdated = self::USE_ANYTHING ) {
-               global $wgCacheEpoch;
-
                if ( is_bool( $useOutdated ) ) {
                        $useOutdated = $useOutdated ? self::USE_ANYTHING : self::USE_CURRENT_ONLY;
                }
@@ -180,7 +185,7 @@ class ParserCache {
                                $cacheTime = $optionsKey->getCacheTime();
                                wfDebugLog( "ParserCache",
                                        "Parser options key expired, touched " . $article->getTouched()
-                                       . ", epoch $wgCacheEpoch, cached $cacheTime\n" );
+                                       . ", epoch {$this->cacheEpoch}, cached $cacheTime\n" );
                                return false;
                        } elseif ( $useOutdated < self::USE_OUTDATED &&
                                $optionsKey->isDifferentRevision( $article->getLatest() )
@@ -221,8 +226,6 @@ class ParserCache {
         * @return ParserOutput|bool False on failure
         */
        public function get( $article, $popts, $useOutdated = false ) {
-               global $wgCacheEpoch;
-
                $canCache = $article->checkTouched();
                if ( !$canCache ) {
                        // It's a redirect now
@@ -264,7 +267,7 @@ class ParserCache {
                        $cacheTime = $value->getCacheTime();
                        wfDebugLog( "ParserCache",
                                "ParserOutput key expired, touched $touched, "
-                               . "epoch $wgCacheEpoch, cached $cacheTime\n" );
+                               . "epoch {$this->cacheEpoch}, cached $cacheTime\n" );
                        $value = false;
                } elseif ( !$useOutdated && $value->isDifferentRevision( $article->getLatest() ) ) {
                        wfIncrStats( "pcache.miss.revid" );
@@ -342,4 +345,15 @@ class ParserCache {
                        wfDebug( "Parser output was marked as uncacheable and has not been saved.\n" );
                }
        }
+
+       /**
+        * Get the backend BagOStuff instance that
+        * powers the parser cache
+        *
+        * @since 1.30
+        * @return BagOStuff
+        */
+       public function getCacheStorage() {
+               return $this->mMemc;
+       }
 }
index e00a55d..da2d850 100644 (file)
@@ -24,6 +24,8 @@
 
 require __DIR__ . '/Maintenance.php';
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Maintenance script to remove old objects from the parser cache.
  *
@@ -67,7 +69,7 @@ class PurgeParserCache extends Maintenance {
                $this->output( "Deleting objects expiring before " .
                        $english->timeanddate( $date ) . "\n" );
 
-               $pc = wfGetParserCacheStorage();
+               $pc = MediaWikiServices::getInstance()->getParserCache()->getCacheStorage();
                $success = $pc->deleteObjectsExpiringBefore( $date, [ $this, 'showProgressAndWait' ] );
                if ( !$success ) {
                        $this->error( "\nCannot purge this kind of parser cache.", 1 );
index b4e9626..4e16258 100644 (file)
@@ -317,6 +317,7 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        'CryptHKDF' => [ 'CryptHKDF', CryptHKDF::class ],
                        'MediaHandlerFactory' => [ 'MediaHandlerFactory', MediaHandlerFactory::class ],
                        'Parser' => [ 'Parser', Parser::class ],
+                       'ParserCache' => [ 'ParserCache', ParserCache::class ],
                        'GenderCache' => [ 'GenderCache', GenderCache::class ],
                        'LinkCache' => [ 'LinkCache', LinkCache::class ],
                        'LinkRenderer' => [ 'LinkRenderer', LinkRenderer::class ],
index 8366369..f2e6858 100644 (file)
@@ -61,7 +61,6 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                DeferredUpdates::clearPendingUpdates();
                $wgMemc = wfGetMainCache();
                $messageMemc = wfGetMessageCacheStorage();
-               $parserMemc = wfGetParserCacheStorage();
 
                RequestContext::resetMain();
                $context = RequestContext::getMain();