User: Migrate from foreign cache to global cache for UserRightsProxy
[lhc/web/wiklou.git] / includes / objectcache / ObjectCache.php
index c40f696..abb88ba 100644 (file)
@@ -43,16 +43,10 @@ use MediaWiki\Logger\LoggerFactory;
  * Primary entry points:
  *
  * - ObjectCache::newAccelerator( $fallbackType )
- *   Purpose: Cache.
+ *   Purpose: Cache for very hot keys.
  *   Stored only on the individual web server.
  *   Not associated with other servers.
  *
- * - ObjectCache::getMainClusterInstance()
- *   Purpose: Cache.
- *   Stored centrally within the local data-center.
- *   Not replicated to other DCs.
- *   Also known as $wgMemc. Configured by $wgMainCacheType.
- *
  * - ObjectCache::getMainWANInstance()
  *   Purpose: Cache.
  *   Stored in the local data-center's main cache (uses different cache keys).
@@ -60,21 +54,30 @@ use MediaWiki\Logger\LoggerFactory;
  *
  * - ObjectCache::getMainStashInstance()
  *   Purpose: Ephemeral storage.
- *   Stored centrally within the local data-center.
- *   Changes are replicated to other DCs (eventually consistent).
+ *   Stored centrally within the primary data-center.
+ *   Changes are applied there first and replicated to other DCs (best-effort).
  *   To retrieve the latest value (e.g. not from a slave), use BagOStuff:READ_LATEST.
  *   This store may be subject to LRU style evictions.
  *
+ * - ObjectCache::getLocalClusterInstance()
+ *   Purpose: Memory storage for per-cluster coordination and tracking.
+ *   A typical use case would be a rate limit counter or cache regeneration mutex.
+ *   Stored centrally within the local data-center. Not replicated to other DCs.
+ *   Also known as $wgMemc. Configured by $wgMainCacheType.
+ *
  * - wfGetCache( $cacheType )
  *   Get a specific cache type by key in $wgObjectCaches.
  *
+ * All the above cache instances (BagOStuff and WANObjectCache) have their makeKey()
+ * method scoped to the *current* wiki ID. Use makeGlobalKey() to avoid this scoping
+ * when using keys that need to be shared amongst wikis.
+ *
  * @ingroup Cache
  */
 class ObjectCache {
-       /** @var Array Map of (id => BagOStuff) */
+       /** @var BagOStuff[] Map of (id => BagOStuff) */
        public static $instances = array();
-
-       /** @var Array Map of (id => WANObjectCache) */
+       /** @var WANObjectCache[] Map of (id => WANObjectCache) */
        public static $wanInstances = array();
 
        /**
@@ -124,6 +127,26 @@ class ObjectCache {
                return self::newFromParams( $wgObjectCaches[$id] );
        }
 
+       /**
+        * Get the default keyspace for this wiki.
+        *
+        * This is either the value of the `CachePrefix` configuration variable,
+        * or (if the former is unset) the `DBname` configuration variable, with
+        * `DBprefix` (if defined).
+        *
+        * @return string
+        */
+       public static function getDefaultKeyspace() {
+               global $wgCachePrefix;
+
+               $keyspace = $wgCachePrefix;
+               if ( is_string( $keyspace ) && $keyspace !== '' ) {
+                       return $keyspace;
+               }
+
+               return wfWikiID();
+       }
+
        /**
         * Create a new cache object from parameters.
         *
@@ -139,14 +162,36 @@ class ObjectCache {
                if ( isset( $params['loggroup'] ) ) {
                        $params['logger'] = LoggerFactory::getInstance( $params['loggroup'] );
                } else {
-                       // For backwards-compatability with custom parameters, lets not
-                       // have all logging suddenly disappear
                        $params['logger'] = LoggerFactory::getInstance( 'objectcache' );
                }
+               if ( !isset( $params['keyspace'] ) ) {
+                       $params['keyspace'] = self::getDefaultKeyspace();
+               }
                if ( isset( $params['factory'] ) ) {
                        return call_user_func( $params['factory'], $params );
                } elseif ( isset( $params['class'] ) ) {
                        $class = $params['class'];
+                       // Automatically set the 'async' update handler
+                       if ( $class === 'MultiWriteBagOStuff' ) {
+                               $params['asyncHandler'] = isset( $params['asyncHandler'] )
+                                       ? $params['asyncHandler']
+                                       : 'DeferredUpdates::addCallableUpdate';
+                       }
+                       // Do b/c logic for MemcachedBagOStuff
+                       if ( is_subclass_of( $class, 'MemcachedBagOStuff' ) ) {
+                               if ( !isset( $params['servers'] ) ) {
+                                       $params['servers'] = $GLOBALS['wgMemCachedServers'];
+                               }
+                               if ( !isset( $params['debug'] ) ) {
+                                       $params['debug'] = $GLOBALS['wgMemCachedDebug'];
+                               }
+                               if ( !isset( $params['persistent'] ) ) {
+                                       $params['persistent'] = $GLOBALS['wgMemCachedPersistent'];
+                               }
+                               if ( !isset( $params['timeout'] ) ) {
+                                       $params['timeout'] = $GLOBALS['wgMemCachedTimeout'];
+                               }
+                       }
                        return new $class( $params );
                } else {
                        throw new MWException( "The definition of cache type \""
@@ -219,21 +264,7 @@ class ObjectCache {
                        }
                        $id = $fallback;
                }
-               return self::newFromId( $id );
-       }
-
-       /**
-        * Factory function that creates a memcached client object.
-        *
-        * This always uses the PHP client, since the PECL client has a different
-        * hashing scheme and a different interpretation of the flags bitfield, so
-        * switching between the two clients randomly would be disastrous.
-        *
-        * @param array $params
-        * @return MemcachedPhpBagOStuff
-        */
-       public static function newMemcached( $params ) {
-               return new MemcachedPhpBagOStuff( $params );
+               return self::getInstance( $id );
        }
 
        /**
@@ -256,6 +287,11 @@ class ObjectCache {
                $class = $params['relayerConfig']['class'];
                $params['relayer'] = new $class( $params['relayerConfig'] );
                $params['cache'] = self::newFromId( $params['cacheId'] );
+               if ( isset( $params['loggroup'] ) ) {
+                       $params['logger'] = LoggerFactory::getInstance( $params['loggroup'] );
+               } else {
+                       $params['logger'] = LoggerFactory::getInstance( 'objectcache' );
+               }
                $class = $params['class'];
 
                return new $class( $params );
@@ -267,10 +303,10 @@ class ObjectCache {
         * @since 1.27
         * @return BagOStuff
         */
-       public static function getMainClusterInstance() {
-               $config = RequestContext::getMain()->getConfig();
-               $id = $config->get( 'MainCacheType' );
-               return self::getInstance( $id );
+       public static function getLocalClusterInstance() {
+               global $wgMainCacheType;
+
+               return self::getInstance( $wgMainCacheType );
        }
 
        /**