MediaWiki  master
ObjectCache.php
Go to the documentation of this file.
1 <?php
26 
68 class ObjectCache {
70  public static $instances = [];
72  public static $wanInstances = [];
73 
80  public static function getInstance( $id ) {
81  if ( !isset( self::$instances[$id] ) ) {
82  self::$instances[$id] = self::newFromId( $id );
83  }
84 
85  return self::$instances[$id];
86  }
87 
95  public static function getWANInstance( $id ) {
96  if ( !isset( self::$wanInstances[$id] ) ) {
97  self::$wanInstances[$id] = self::newWANCacheFromId( $id );
98  }
99 
100  return self::$wanInstances[$id];
101  }
102 
110  private static function newFromId( $id ) {
111  global $wgObjectCaches;
112 
113  if ( !isset( $wgObjectCaches[$id] ) ) {
114  // Always recognize these ones
115  if ( $id === CACHE_NONE ) {
116  return new EmptyBagOStuff();
117  } elseif ( $id === 'hash' ) {
118  return new HashBagOStuff();
119  }
120 
121  throw new InvalidArgumentException( "Invalid object cache type \"$id\" requested. " .
122  "It is not present in \$wgObjectCaches." );
123  }
124 
125  return self::newFromParams( $wgObjectCaches[$id] );
126  }
127 
137  private static function getDefaultKeyspace() {
138  global $wgCachePrefix;
139 
140  $keyspace = $wgCachePrefix;
141  if ( is_string( $keyspace ) && $keyspace !== '' ) {
142  return $keyspace;
143  }
144 
145  return WikiMap::getCurrentWikiDbDomain()->getId();
146  }
147 
159  public static function newFromParams( $params ) {
160  $params['logger'] = LoggerFactory::getInstance( $params['loggroup'] ?? 'objectcache' );
161  if ( !isset( $params['keyspace'] ) ) {
162  $params['keyspace'] = self::getDefaultKeyspace();
163  }
164  if ( isset( $params['factory'] ) ) {
165  return call_user_func( $params['factory'], $params );
166  } elseif ( isset( $params['class'] ) ) {
167  $class = $params['class'];
168  // Automatically set the 'async' update handler
169  $params['asyncHandler'] = $params['asyncHandler']
170  ?? [ DeferredUpdates::class, 'addCallableUpdate' ];
171  // Enable reportDupes by default
172  $params['reportDupes'] = $params['reportDupes'] ?? true;
173  // Do b/c logic for SqlBagOStuff
174  if ( is_a( $class, SqlBagOStuff::class, true ) ) {
175  if ( isset( $params['server'] ) && !isset( $params['servers'] ) ) {
176  $params['servers'] = [ $params['server'] ];
177  unset( $params['server'] );
178  }
179  // In the past it was not required to set 'dbDirectory' in $wgObjectCaches
180  if ( isset( $params['servers'] ) ) {
181  foreach ( $params['servers'] as &$server ) {
182  if ( $server['type'] === 'sqlite' && !isset( $server['dbDirectory'] ) ) {
183  $server['dbDirectory'] = MediaWikiServices::getInstance()
184  ->getMainConfig()->get( 'SQLiteDataDir' );
185  }
186  }
187  }
188  }
189 
190  // Do b/c logic for MemcachedBagOStuff
191  if ( is_subclass_of( $class, MemcachedBagOStuff::class ) ) {
192  if ( !isset( $params['servers'] ) ) {
193  $params['servers'] = $GLOBALS['wgMemCachedServers'];
194  }
195  if ( !isset( $params['persistent'] ) ) {
196  $params['persistent'] = $GLOBALS['wgMemCachedPersistent'];
197  }
198  if ( !isset( $params['timeout'] ) ) {
199  $params['timeout'] = $GLOBALS['wgMemCachedTimeout'];
200  }
201  }
202  return new $class( $params );
203  } else {
204  throw new InvalidArgumentException( "The definition of cache type \""
205  . print_r( $params, true ) . "\" lacks both "
206  . "factory and class parameters." );
207  }
208  }
209 
223  public static function newAnything( $params ) {
226  foreach ( $candidates as $candidate ) {
227  if ( $candidate !== CACHE_NONE && $candidate !== CACHE_ANYTHING ) {
228  $cache = self::getInstance( $candidate );
229  // CACHE_ACCEL might default to nothing if no APCu
230  // See includes/ServiceWiring.php
231  if ( !( $cache instanceof EmptyBagOStuff ) ) {
232  return $cache;
233  }
234  }
235  }
236 
237  if ( MediaWikiServices::getInstance()->isServiceDisabled( 'DBLoadBalancer' ) ) {
238  // The LoadBalancer is disabled, probably because
239  // MediaWikiServices::disableStorageBackend was called.
240  $candidate = CACHE_NONE;
241  } else {
242  $candidate = CACHE_DB;
243  }
244 
245  return self::getInstance( $candidate );
246  }
247 
265  public static function getLocalServerInstance( $fallback = CACHE_NONE ) {
266  $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
267  if ( $cache instanceof EmptyBagOStuff ) {
268  if ( is_array( $fallback ) ) {
269  $fallback = $fallback['fallback'] ?? CACHE_NONE;
270  }
271  $cache = self::getInstance( $fallback );
272  }
273 
274  return $cache;
275  }
276 
285  private static function newWANCacheFromId( $id ) {
287 
288  if ( !isset( $wgWANObjectCaches[$id] ) ) {
289  throw new UnexpectedValueException(
290  "Cache type \"$id\" requested is not present in \$wgWANObjectCaches." );
291  }
292 
293  $params = $wgWANObjectCaches[$id];
294  if ( !isset( $wgObjectCaches[$params['cacheId']] ) ) {
295  throw new UnexpectedValueException(
296  "Cache type \"{$params['cacheId']}\" is not present in \$wgObjectCaches." );
297  }
298  $params['store'] = $wgObjectCaches[$params['cacheId']];
299 
300  return self::newWANCacheFromParams( $params );
301  }
302 
312  public static function newWANCacheFromParams( array $params ) {
314 
315  $services = MediaWikiServices::getInstance();
316  $params['cache'] = self::newFromParams( $params['store'] );
317  $params['logger'] = LoggerFactory::getInstance( $params['loggroup'] ?? 'objectcache' );
318  if ( !$wgCommandLineMode ) {
319  // Send the statsd data post-send on HTTP requests; avoid in CLI mode (T181385)
320  $params['stats'] = $services->getStatsdDataFactory();
321  // Let pre-emptive refreshes happen post-send on HTTP requests
322  $params['asyncHandler'] = [ DeferredUpdates::class, 'addCallableUpdate' ];
323  }
324  $params['secret'] = $params['secret'] ?? $wgSecretKey;
325  $class = $params['class'];
326 
327  return new $class( $params );
328  }
329 
336  public static function getLocalClusterInstance() {
337  global $wgMainCacheType;
338 
339  return self::getInstance( $wgMainCacheType );
340  }
341 
345  public static function clear() {
346  self::$instances = [];
347  self::$wanInstances = [];
348  }
349 
356  public static function detectLocalServerCache() {
357  if ( function_exists( 'apcu_fetch' ) ) {
358  // Make sure the APCu methods actually store anything
359  if ( PHP_SAPI !== 'cli' || ini_get( 'apc.enable_cli' ) ) {
360  return 'apcu';
361  }
362  } elseif ( function_exists( 'apc_fetch' ) ) {
363  // Make sure the APC methods actually store anything
364  if ( PHP_SAPI !== 'cli' || ini_get( 'apc.enable_cli' ) ) {
365  return 'apc';
366  }
367  } elseif ( function_exists( 'wincache_ucache_get' ) ) {
368  return 'wincache';
369  }
370 
371  return CACHE_NONE;
372  }
373 }
static newAnything( $params)
Factory function for CACHE_ANYTHING (referenced from DefaultSettings.php)
$wgSecretKey
This should always be customised in LocalSettings.php.
static newWANCacheFromParams(array $params)
Create a new cache object of the specified type.
static getInstance( $id)
Get a cached instance of the specified type of cache object.
Definition: ObjectCache.php:80
static getLocalClusterInstance()
Get the main cluster-local cache object.
$wgWANObjectCaches
Advanced WAN object cache configuration.
static getWANInstance( $id)
Get a cached instance of the specified type of WAN cache object.
Definition: ObjectCache.php:95
static BagOStuff [] $instances
Map of (id => BagOStuff)
Definition: ObjectCache.php:70
$wgParserCacheType
The cache type for storing article HTML.
$wgMainCacheType
Main cache type.
$wgMessageCacheType
The cache type for storing the contents of the MediaWiki namespace.
$cache
Definition: mcc.php:33
$wgCachePrefix
Overwrite the caching key prefix with custom value.
static getDefaultKeyspace()
Get the default keyspace for this wiki.
$GLOBALS['IP']
static WANObjectCache [] $wanInstances
Map of (id => WANObjectCache)
Definition: ObjectCache.php:72
static getCurrentWikiDbDomain()
Definition: WikiMap.php:292
$fallback
Definition: MessagesAb.php:11
static newFromParams( $params)
Create a new cache object from parameters.
static newWANCacheFromId( $id)
Create a new cache object of the specified type.
global $wgCommandLineMode
static newFromId( $id)
Create a new cache object of the specified type.
const CACHE_ANYTHING
Definition: Defines.php:81
static getLocalServerInstance( $fallback=CACHE_NONE)
Factory function for CACHE_ACCEL (referenced from DefaultSettings.php)
$wgObjectCaches
Advanced object cache configuration.
static clear()
Clear all the cached instances.
static detectLocalServerCache()
Detects which local server cache library is present and returns a configuration for it...
const CACHE_NONE
Definition: Defines.php:82
const CACHE_DB
Definition: Defines.php:83