diff options
Diffstat (limited to 'includes/objectcache/ObjectCache.php')
-rw-r--r-- | includes/objectcache/ObjectCache.php | 209 |
1 files changed, 36 insertions, 173 deletions
diff --git a/includes/objectcache/ObjectCache.php b/includes/objectcache/ObjectCache.php index 91ea0a57daee..129bb46d1268 100644 --- a/includes/objectcache/ObjectCache.php +++ b/includes/objectcache/ObjectCache.php @@ -21,12 +21,7 @@ * @ingroup Cache */ -use MediaWiki\Deferred\DeferredUpdates; -use MediaWiki\Http\Telemetry; -use MediaWiki\Logger\LoggerFactory; -use MediaWiki\MainConfigNames; use MediaWiki\MediaWikiServices; -use MediaWiki\WikiMap\WikiMap; /** * Functions to get cache objects @@ -66,7 +61,10 @@ use MediaWiki\WikiMap\WikiMap; * @ingroup Cache */ class ObjectCache { - /** @var BagOStuff[] Map of (id => BagOStuff) */ + /** + * @deprecated Use ObjectCacheFactory instead. + * @var BagOStuff[] Map of (id => BagOStuff) + */ public static $instances = []; /** @@ -78,157 +76,26 @@ class ObjectCache { /** * Get a cached instance of the specified type of cache object. * - * @param string|int $id A key in $wgObjectCaches. - * @return BagOStuff - */ - public static function getInstance( $id ) { - if ( !isset( self::$instances[$id] ) ) { - self::$instances[$id] = self::newFromId( $id ); - } - - return self::$instances[$id]; - } - - /** - * Create a new cache object of the specified type. + * @deprecated Use ObjectCacheFactory::getInstance instead. * * @param string|int $id A key in $wgObjectCaches. * @return BagOStuff - * @throws InvalidArgumentException */ - private static function newFromId( $id ) { - global $wgObjectCaches; - - if ( !isset( $wgObjectCaches[$id] ) ) { - // Always recognize these ones - if ( $id === CACHE_NONE ) { - return new EmptyBagOStuff(); - } elseif ( $id === CACHE_HASH ) { - return new HashBagOStuff(); - } - - throw new InvalidArgumentException( "Invalid object cache type \"$id\" requested. " . - "It is not present in \$wgObjectCaches." ); - } - - return self::newFromParams( $wgObjectCaches[$id] ); + public static function getInstance( $id ) { + return MediaWikiServices::getInstance()->getObjectCacheFactory()->getInstance( $id ); } /** - * Get the default keyspace for this wiki. + * @see ObjectCacheFactory::newFromParams() * - * 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 - */ - private static function getDefaultKeyspace() { - global $wgCachePrefix; - - $keyspace = $wgCachePrefix; - if ( is_string( $keyspace ) && $keyspace !== '' ) { - return $keyspace; - } - - return WikiMap::getCurrentWikiDbDomain()->getId(); - } - - /** - * Create a new cache object from parameters. + * @deprecated since 1.42, Use ObjectCacheFactory::newFromParams instead. + * @param array $params * - * @param array $params Must have 'factory' or 'class' property. - * - factory: Callback passed $params that returns BagOStuff. - * - class: BagOStuff subclass constructed with $params. - * - loggroup: Alias to set 'logger' key with LoggerFactory group. - * - .. Other parameters passed to factory or class. - * @param MediaWikiServices|null $services [internal] * @return BagOStuff */ - public static function newFromParams( array $params, MediaWikiServices $services = null ) { - $services ??= MediaWikiServices::getInstance(); - $conf = $services->getMainConfig(); - - // Apply default parameters and resolve the logger instance - $params += [ - 'logger' => LoggerFactory::getInstance( $params['loggroup'] ?? 'objectcache' ), - 'keyspace' => self::getDefaultKeyspace(), - 'asyncHandler' => [ DeferredUpdates::class, 'addCallableUpdate' ], - 'reportDupes' => true, - 'stats' => $services->getStatsFactory(), - ]; - - if ( isset( $params['factory'] ) ) { - $args = $params['args'] ?? [ $params ]; - - return call_user_func( $params['factory'], ...$args ); - } - - if ( !isset( $params['class'] ) ) { - throw new InvalidArgumentException( - 'No "factory" nor "class" provided; got "' . print_r( $params, true ) . '"' - ); - } - - $class = $params['class']; - - // Normalization and DI for SqlBagOStuff - if ( is_a( $class, SqlBagOStuff::class, true ) ) { - if ( isset( $params['globalKeyLB'] ) ) { - throw new InvalidArgumentException( - 'globalKeyLB in $wgObjectCaches is no longer supported' ); - } - if ( isset( $params['server'] ) && !isset( $params['servers'] ) ) { - $params['servers'] = [ $params['server'] ]; - unset( $params['server'] ); - } - if ( isset( $params['servers'] ) ) { - // In the past it was not required to set 'dbDirectory' in $wgObjectCaches - foreach ( $params['servers'] as &$server ) { - if ( $server['type'] === 'sqlite' && !isset( $server['dbDirectory'] ) ) { - $server['dbDirectory'] = $conf->get( MainConfigNames::SQLiteDataDir ); - } - } - } elseif ( isset( $params['cluster'] ) ) { - $cluster = $params['cluster']; - $params['loadBalancerCallback'] = static function () use ( $services, $cluster ) { - return $services->getDBLoadBalancerFactory()->getExternalLB( $cluster ); - }; - $params += [ 'dbDomain' => false ]; - } else { - $params['loadBalancerCallback'] = static function () use ( $services ) { - return $services->getDBLoadBalancer(); - }; - $params += [ 'dbDomain' => false ]; - } - $params += [ 'writeBatchSize' => $conf->get( MainConfigNames::UpdateRowsPerQuery ) ]; - } - - // Normalization and DI for MemcachedBagOStuff - if ( is_subclass_of( $class, MemcachedBagOStuff::class ) ) { - $params += [ - 'servers' => $conf->get( MainConfigNames::MemCachedServers ), - 'persistent' => $conf->get( MainConfigNames::MemCachedPersistent ), - 'timeout' => $conf->get( MainConfigNames::MemCachedTimeout ), - ]; - } - - // Normalization and DI for MultiWriteBagOStuff - if ( is_a( $class, MultiWriteBagOStuff::class, true ) ) { - // Phan warns about foreach with non-array because it - // thinks any key can be Closure|IBufferingStatsdDataFactory - '@phan-var array{caches:array[]} $params'; - foreach ( $params['caches'] ?? [] as $i => $cacheInfo ) { - // Ensure logger, keyspace, asyncHandler, etc are injected just as if - // one of these was configured without MultiWriteBagOStuff. - $params['caches'][$i] = self::newFromParams( $cacheInfo, $services ); - } - } - if ( is_a( $class, RESTBagOStuff::class, true ) ) { - $params['telemetry'] = Telemetry::getInstance(); - } - - return new $class( $params ); + public static function newFromParams( array $params ) { + return MediaWikiServices::getInstance()->getObjectCacheFactory() + ->newFromParams( $params ); } /** @@ -241,18 +108,23 @@ class ObjectCache { * If no cache choice is configured (by default $wgMainCacheType is CACHE_NONE), * then CACHE_ANYTHING will forward to CACHE_DB. * - * @param array $params + * @deprecated since 1.42, + * Use ObjectCacheFactory::newInstance( ObjectCache::getAnythingId() ); + * * @return BagOStuff */ - public static function newAnything( $params ) { - return self::getInstance( self::getAnythingId() ); + public static function newAnything() { + return MediaWikiServices::getInstance()->getObjectCacheFactory() + ->getInstance( self::getAnythingId() ); } /** + * @internal Used by ObjectCacheFactory and ObjectCache. + * * Get the ID that will be used for CACHE_ANYTHING * @return string|int */ - private static function getAnythingId() { + public static function getAnythingId() { global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType; $candidates = [ $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType ]; foreach ( $candidates as $candidate ) { @@ -284,16 +156,8 @@ class ObjectCache { } /** - * Factory function for CACHE_ACCEL (referenced from configuration) - * - * This will look for any APC or APCu style server-local cache. - * A fallback cache can be specified if none is found. - * - * // Direct calls - * ObjectCache::getLocalServerInstance( $fallbackType ); - * - * // From $wgObjectCaches via newFromParams() - * ObjectCache::getLocalServerInstance( [ 'fallback' => $fallbackType ] ); + * @deprecated since 1.42, Use ObjectCacheFactory::getLocaServerInstance() + * @see ObjectCacheFactory::getLocalServerInstance() * * @param int|string|array $fallback Fallback cache or parameter map with 'fallback' * @return BagOStuff @@ -301,15 +165,8 @@ class ObjectCache { * @since 1.27 */ public static function getLocalServerInstance( $fallback = CACHE_NONE ) { - $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache(); - if ( $cache instanceof EmptyBagOStuff ) { - if ( is_array( $fallback ) ) { - $fallback = $fallback['fallback'] ?? CACHE_NONE; - } - $cache = self::getInstance( $fallback ); - } - - return $cache; + return MediaWikiServices::getInstance()->getObjectCacheFactory() + ->getLocalServerInstance( $fallback ); } /** @@ -337,7 +194,7 @@ class ObjectCache { if ( ( $cache['class'] ?? '' ) === SqlBagOStuff::class ) { return true; } - if ( ( $cache['factory'] ?? '' ) === 'ObjectCache::newAnything' ) { + if ( $id === CACHE_ANYTHING ) { $id = self::getAnythingId(); return self::isDatabaseId( $id ); } @@ -345,10 +202,12 @@ class ObjectCache { } /** + * @deprecated since 1.42, Use ObjectCacheFactory::clear() instead. + * * Clear all the cached instances. */ public static function clear() { - self::$instances = []; + MediaWikiServices::getInstance()->getObjectCacheFactory()->clear(); } /** @@ -362,14 +221,18 @@ class ObjectCache { * and thus must remain fairly standalone so as to not cause initialization * of the MediaWikiServices singleton. * + * @internal For use by ServiceWiring and ExtensionRegistry. There are use + * cases whereby we want to build up local server cache without service + * wiring available. * @since 1.35 + * @param string|false $cachePrefix * @return BagOStuff */ - public static function makeLocalServerCache(): BagOStuff { + public static function makeLocalServerCache( $cachePrefix ): BagOStuff { $params = [ 'reportDupes' => false, // Even simple caches must use a keyspace (T247562) - 'keyspace' => self::getDefaultKeyspace(), + 'keyspace' => $cachePrefix, ]; $class = self::getLocalServerCacheClass(); return new $class( $params ); |