MediaWiki REL1_40
ObjectCache.php
Go to the documentation of this file.
1<?php
28
68 public static $instances = [];
69
76 public static function getInstance( $id ) {
77 if ( !isset( self::$instances[$id] ) ) {
78 self::$instances[$id] = self::newFromId( $id );
79 }
80
81 return self::$instances[$id];
82 }
83
91 private static function newFromId( $id ) {
92 global $wgObjectCaches;
93
94 if ( !isset( $wgObjectCaches[$id] ) ) {
95 // Always recognize these ones
96 if ( $id === CACHE_NONE ) {
97 return new EmptyBagOStuff();
98 } elseif ( $id === CACHE_HASH ) {
99 return new HashBagOStuff();
100 }
101
102 throw new InvalidArgumentException( "Invalid object cache type \"$id\" requested. " .
103 "It is not present in \$wgObjectCaches." );
104 }
105
106 return self::newFromParams( $wgObjectCaches[$id] );
107 }
108
118 private static function getDefaultKeyspace() {
119 global $wgCachePrefix;
120
121 $keyspace = $wgCachePrefix;
122 if ( is_string( $keyspace ) && $keyspace !== '' ) {
123 return $keyspace;
124 }
125
126 return WikiMap::getCurrentWikiDbDomain()->getId();
127 }
128
140 public static function newFromParams( array $params, MediaWikiServices $services = null ) {
141 $services ??= MediaWikiServices::getInstance();
142 $conf = $services->getMainConfig();
143
144 // Apply default parameters and resolve the logger instance
145 $params += [
146 'logger' => LoggerFactory::getInstance( $params['loggroup'] ?? 'objectcache' ),
147 'keyspace' => self::getDefaultKeyspace(),
148 'asyncHandler' => [ DeferredUpdates::class, 'addCallableUpdate' ],
149 'reportDupes' => true,
150 'stats' => $services->getStatsdDataFactory(),
151 ];
152
153 if ( isset( $params['factory'] ) ) {
154 $args = $params['args'] ?? [ $params ];
155
156 return call_user_func( $params['factory'], ...$args );
157 }
158
159 if ( !isset( $params['class'] ) ) {
160 throw new InvalidArgumentException(
161 'No "factory" nor "class" provided; got "' . print_r( $params, true ) . '"'
162 );
163 }
164
165 $class = $params['class'];
166
167 // Normalization and DI for SqlBagOStuff
168 if ( is_a( $class, SqlBagOStuff::class, true ) ) {
169 if ( isset( $params['globalKeyLB'] ) ) {
170 throw new InvalidArgumentException(
171 'globalKeyLB in $wgObjectCaches is no longer supported' );
172 }
173 if ( isset( $params['server'] ) && !isset( $params['servers'] ) ) {
174 $params['servers'] = [ $params['server'] ];
175 unset( $params['server'] );
176 }
177 if ( isset( $params['servers'] ) ) {
178 // In the past it was not required to set 'dbDirectory' in $wgObjectCaches
179 foreach ( $params['servers'] as &$server ) {
180 if ( $server['type'] === 'sqlite' && !isset( $server['dbDirectory'] ) ) {
181 $server['dbDirectory'] = $conf->get( MainConfigNames::SQLiteDataDir );
182 }
183 }
184 } elseif ( isset( $params['cluster'] ) ) {
185 $cluster = $params['cluster'];
186 $params['loadBalancerCallback'] = static function () use ( $services, $cluster ) {
187 return $services->getDBLoadBalancerFactory()->getExternalLB( $cluster );
188 };
189 $params += [ 'dbDomain' => false ];
190 } else {
191 $params['loadBalancerCallback'] = static function () use ( $services ) {
192 return $services->getDBLoadBalancer();
193 };
194 $params += [ 'dbDomain' => false ];
195 }
196 $params += [ 'writeBatchSize' => $conf->get( MainConfigNames::UpdateRowsPerQuery ) ];
197 }
198
199 // Normalization and DI for MemcachedBagOStuff
200 if ( is_subclass_of( $class, MemcachedBagOStuff::class ) ) {
201 $params += [
202 'servers' => $conf->get( MainConfigNames::MemCachedServers ),
203 'persistent' => $conf->get( MainConfigNames::MemCachedPersistent ),
204 'timeout' => $conf->get( MainConfigNames::MemCachedTimeout ),
205 ];
206 }
207
208 // Normalization and DI for MultiWriteBagOStuff
209 if ( is_a( $class, MultiWriteBagOStuff::class, true ) ) {
210 // Phan warns about foreach with non-array because it
211 // thinks any key can be Closure|IBufferingStatsdDataFactory
212 '@phan-var array{caches:array[]} $params';
213 foreach ( $params['caches'] ?? [] as $i => $cacheInfo ) {
214 // Ensure logger, keyspace, asyncHandler, etc are injected just as if
215 // one of these was configured without MultiWriteBagOStuff.
216 $params['caches'][$i] = self::newFromParams( $cacheInfo, $services );
217 }
218 }
219
220 return new $class( $params );
221 }
222
236 public static function newAnything( $params ) {
239 foreach ( $candidates as $candidate ) {
240 if ( $candidate !== CACHE_NONE && $candidate !== CACHE_ANYTHING ) {
241 $cache = self::getInstance( $candidate );
242 // CACHE_ACCEL might default to nothing if no APCu
243 // See includes/ServiceWiring.php
244 if ( !( $cache instanceof EmptyBagOStuff ) ) {
245 return $cache;
246 }
247 }
248 }
249
250 $services = MediaWikiServices::getInstance();
251
252 if ( $services->isServiceDisabled( 'DBLoadBalancer' ) ) {
253 // The DBLoadBalancer service is disabled, so we can't use the database!
254 $candidate = CACHE_NONE;
255 } elseif ( $services->isStorageDisabled() ) {
256 // Storage services are disabled because MediaWikiServices::disableStorage()
257 // was called. This is typically the case during installation.
258 $candidate = CACHE_NONE;
259 } else {
260 $candidate = CACHE_DB;
261 }
262
263 return self::getInstance( $candidate );
264 }
265
283 public static function getLocalServerInstance( $fallback = CACHE_NONE ) {
284 $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
285 if ( $cache instanceof EmptyBagOStuff ) {
286 if ( is_array( $fallback ) ) {
287 $fallback = $fallback['fallback'] ?? CACHE_NONE;
288 }
289 $cache = self::getInstance( $fallback );
290 }
291
292 return $cache;
293 }
294
301 public static function getLocalClusterInstance() {
302 return MediaWikiServices::getInstance()->get( '_LocalClusterCache' );
303 }
304
308 public static function clear() {
309 self::$instances = [];
310 }
311
326 public static function makeLocalServerCache(): BagOStuff {
327 $params = [
328 'reportDupes' => false,
329 // Even simple caches must use a keyspace (T247562)
330 'keyspace' => self::getDefaultKeyspace(),
331 ];
332 if ( function_exists( 'apcu_fetch' ) ) {
333 // Make sure the APCu methods actually store anything
334 if ( PHP_SAPI !== 'cli' || ini_get( 'apc.enable_cli' ) ) {
335 return new APCUBagOStuff( $params );
336 }
337 } elseif ( function_exists( 'wincache_ucache_get' ) ) {
338 return new WinCacheBagOStuff( $params );
339 }
340
341 return new EmptyBagOStuff( $params );
342 }
343}
const CACHE_NONE
Definition Defines.php:86
const CACHE_ANYTHING
Definition Defines.php:85
const CACHE_HASH
Definition Defines.php:90
const CACHE_DB
Definition Defines.php:87
$fallback
Definition MessagesAb.php:8
This is a wrapper for APCu's shared memory functions.
Class representing a cache/ephemeral data store.
Definition BagOStuff.php:85
A BagOStuff object with no objects in it.
Simple store for keeping values in an associative array for the current process.
PSR-3 logger instance factory.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
Helper tools for dealing with other locally-hosted wikis.
Definition WikiMap.php:33
Functions to get cache objects.
static getLocalServerInstance( $fallback=CACHE_NONE)
Factory function for CACHE_ACCEL (referenced from configuration)
static makeLocalServerCache()
Create a new BagOStuff instance for local-server caching.
static newAnything( $params)
Factory function for CACHE_ANYTHING (referenced by configuration)
static clear()
Clear all the cached instances.
static newFromParams(array $params, MediaWikiServices $services=null)
Create a new cache object from parameters.
static BagOStuff[] $instances
Map of (id => BagOStuff)
static getInstance( $id)
Get a cached instance of the specified type of cache object.
static getLocalClusterInstance()
Get the main cluster-local cache object.
Wrapper for WinCache object caching functions; identical interface to the APC wrapper.
$wgObjectCaches
Config variable stub for the ObjectCaches setting, for use by phpdoc and IDEs.
$wgParserCacheType
Config variable stub for the ParserCacheType setting, for use by phpdoc and IDEs.
$wgMainCacheType
Config variable stub for the MainCacheType setting, for use by phpdoc and IDEs.
$wgCachePrefix
Config variable stub for the CachePrefix setting, for use by phpdoc and IDEs.
$wgMessageCacheType
Config variable stub for the MessageCacheType setting, for use by phpdoc and IDEs.