Fix installer issues introduces by MediaWikiServices
[lhc/web/wiklou.git] / includes / objectcache / ObjectCache.php
index 3d14c33..e1bb2db 100644 (file)
@@ -22,6 +22,8 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Services\ServiceDisabledException;
 
 /**
  * Functions to get cache objects
@@ -42,30 +44,32 @@ use MediaWiki\Logger\LoggerFactory;
  *
  * Primary entry points:
  *
- * - ObjectCache::newAccelerator( $fallbackType )
- *   Purpose: Cache for very hot keys.
- *   Stored only on the individual web server.
- *   Not associated with other servers.
- *
  * - ObjectCache::getMainWANInstance()
- *   Purpose: Cache.
- *   Stored in the local data-center's main cache (uses different cache keys).
- *   Delete events are broadcasted to other DCs. See WANObjectCache for details.
+ *   Purpose: Memory cache.
+ *   Stored in the local data-center's main cache (keyspace different from local-cluster cache).
+ *   Delete events are broadcasted to other DCs main cache. See WANObjectCache for details.
  *
- * - ObjectCache::getMainStashInstance()
- *   Purpose: Ephemeral storage.
- *   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::getLocalServerInstance( $fallbackType )
+ *   Purpose: Memory cache for very hot keys.
+ *   Stored only on the individual web server (typically APC for web requests,
+ *   and EmptyBagOStuff in CLI mode).
+ *   Not replicated to the other servers.
  *
  * - 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.
+ *   Configured by $wgMainCacheType.
  *
- * - wfGetCache( $cacheType )
+ * - ObjectCache::getMainStashInstance()
+ *   Purpose: Ephemeral global storage.
+ *   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::getInstance( $cacheType )
+ *   Purpose: Special cases (like tiered memory/disk caches).
  *   Get a specific cache type by key in $wgObjectCaches.
  *
  * All the above cache instances (BagOStuff and WANObjectCache) have their makeKey()
@@ -76,9 +80,9 @@ use MediaWiki\Logger\LoggerFactory;
  */
 class ObjectCache {
        /** @var BagOStuff[] Map of (id => BagOStuff) */
-       public static $instances = array();
+       public static $instances = [];
        /** @var WANObjectCache[] Map of (id => WANObjectCache) */
-       public static $wanInstances = array();
+       public static $wanInstances = [];
 
        /**
         * Get a cached instance of the specified type of cache object.
@@ -137,19 +141,14 @@ class ObjectCache {
         * @return string
         */
        public static function getDefaultKeyspace() {
-               global $wgCachePrefix, $wgDBname, $wgDBprefix;
+               global $wgCachePrefix;
 
                $keyspace = $wgCachePrefix;
                if ( is_string( $keyspace ) && $keyspace !== '' ) {
                        return $keyspace;
                }
 
-               $keyspace = $wgDBname;
-               if ( is_string( $wgDBprefix ) && $wgDBprefix !== '' ) {
-                       $keyspace .= '-' . $wgDBprefix;
-               }
-
-               return $keyspace;
+               return wfWikiID();
        }
 
        /**
@@ -177,11 +176,13 @@ class ObjectCache {
                } 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';
-                       }
+                       $params['asyncHandler'] = isset( $params['asyncHandler'] )
+                               ? $params['asyncHandler']
+                               : 'DeferredUpdates::addCallableUpdate';
+                       // Enable reportDupes by default
+                       $params['reportDupes'] = isset( $params['reportDupes'] )
+                               ? $params['reportDupes']
+                               : true;
                        // Do b/c logic for MemcachedBagOStuff
                        if ( is_subclass_of( $class, 'MemcachedBagOStuff' ) ) {
                                if ( !isset( $params['servers'] ) ) {
@@ -220,13 +221,24 @@ class ObjectCache {
         */
        public static function newAnything( $params ) {
                global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType;
-               $candidates = array( $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType );
+               $candidates = [ $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType ];
                foreach ( $candidates as $candidate ) {
                        if ( $candidate !== CACHE_NONE && $candidate !== CACHE_ANYTHING ) {
                                return self::getInstance( $candidate );
                        }
                }
-               return self::getInstance( CACHE_DB );
+
+               try {
+                       // Make sure we actually have a DB backend before falling back to CACHE_DB
+                       MediaWikiServices::getInstance()->getDBLoadBalancer();
+                       $candidate = CACHE_DB;
+               } catch ( ServiceDisabledException $e ) {
+                       // The LoadBalancer is disabled, probably because
+                       // MediaWikiServices::disableStorageBackend was called.
+                       $candidate = CACHE_NONE;
+               }
+
+               return self::getInstance( $candidate );
        }
 
        /**
@@ -236,26 +248,17 @@ class ObjectCache {
         * A fallback cache can be specified if none is found.
         *
         *     // Direct calls
-        *     ObjectCache::newAccelerator( $fallbackType );
+        *     ObjectCache::getLocalServerInstance( $fallbackType );
         *
         *     // From $wgObjectCaches via newFromParams()
-        *     ObjectCache::newAccelerator( array( 'fallback' => $fallbackType ) );
+        *     ObjectCache::getLocalServerInstance( array( 'fallback' => $fallbackType ) );
         *
-        * @param array $params [optional] Array key 'fallback' for $fallback.
-        * @param int|string $fallback Fallback cache, e.g. (CACHE_NONE, "hash") (since 1.24)
+        * @param int|string|array $fallback Fallback cache or parameter map with 'fallback'
         * @return BagOStuff
         * @throws MWException
+        * @since 1.27
         */
-       public static function newAccelerator( $params = array(), $fallback = null ) {
-               if ( $fallback === null ) {
-                       // The is_array check here is needed because in PHP 5.3:
-                       // $a = 'hash'; isset( $params['fallback'] ); yields true
-                       if ( is_array( $params ) && isset( $params['fallback'] ) ) {
-                               $fallback = $params['fallback'];
-                       } elseif ( !is_array( $params ) ) {
-                               $fallback = $params;
-                       }
-               }
+       public static function getLocalServerInstance( $fallback = CACHE_NONE ) {
                if ( function_exists( 'apc_fetch' ) ) {
                        $id = 'apc';
                } elseif ( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
@@ -263,15 +266,34 @@ class ObjectCache {
                } elseif ( function_exists( 'wincache_ucache_get' ) ) {
                        $id = 'wincache';
                } else {
-                       if ( $fallback === null ) {
-                               throw new MWException( 'CACHE_ACCEL requested but no suitable object ' .
-                                       'cache is present. You may want to install APC.' );
+                       if ( is_array( $fallback ) ) {
+                               $id = isset( $fallback['fallback'] ) ? $fallback['fallback'] : CACHE_NONE;
+                       } else {
+                               $id = $fallback;
                        }
-                       $id = $fallback;
                }
+
                return self::getInstance( $id );
        }
 
+       /**
+        * @param array $params [optional] Array key 'fallback' for $fallback.
+        * @param int|string $fallback Fallback cache, e.g. (CACHE_NONE, "hash") (since 1.24)
+        * @return BagOStuff
+        * @deprecated 1.27
+        */
+       public static function newAccelerator( $params = [], $fallback = null ) {
+               if ( $fallback === null ) {
+                       if ( is_array( $params ) && isset( $params['fallback'] ) ) {
+                               $fallback = $params['fallback'];
+                       } elseif ( !is_array( $params ) ) {
+                               $fallback = $params;
+                       }
+               }
+
+               return self::getLocalServerInstance( $fallback );
+       }
+
        /**
         * Create a new cache object of the specified type.
         *
@@ -289,8 +311,11 @@ class ObjectCache {
                }
 
                $params = $wgWANObjectCaches[$id];
-               $class = $params['relayerConfig']['class'];
-               $params['relayer'] = new $class( $params['relayerConfig'] );
+               foreach ( $params['channels'] as $action => $channel ) {
+                       $params['relayers'][$action] = MediaWikiServices::getInstance()->getEventRelayerGroup()
+                               ->getRelayer( $channel );
+                       $params['channels'][$action] = $channel;
+               }
                $params['cache'] = self::newFromId( $params['cacheId'] );
                if ( isset( $params['loggroup'] ) ) {
                        $params['logger'] = LoggerFactory::getInstance( $params['loggroup'] );
@@ -354,7 +379,7 @@ class ObjectCache {
         * Clear all the cached instances.
         */
        public static function clear() {
-               self::$instances = array();
-               self::$wanInstances = array();
+               self::$instances = [];
+               self::$wanInstances = [];
        }
 }