9use InvalidArgumentException;
84 private $instances = [];
85 private string $domainId;
87 private $dbLoadBalancerFactory;
98 callable $dbLoadBalancerFactory,
103 $this->options = $options;
104 $this->stats = $stats;
105 $this->logger = $loggerSpi;
106 $this->dbLoadBalancerFactory = $dbLoadBalancerFactory;
107 $this->domainId = $domainId;
108 $this->telemetry = $telemetry;
118 private function getDefaultKeyspace(): string {
120 if ( is_string( $cachePrefix ) && $cachePrefix !==
'' ) {
124 return $this->domainId;
133 private function newFromId( $id ): BagOStuff {
135 $id = $this->getAnythingId();
141 return new EmptyBagOStuff();
143 return new HashBagOStuff();
145 return self::makeLocalServerCache( $this->getDefaultKeyspace() );
146 } elseif ( $id ===
'wincache' ) {
147 wfDeprecated( __METHOD__ .
' with cache ID "wincache"',
'1.43' );
148 return self::makeLocalServerCache( $this->getDefaultKeyspace() );
151 throw new InvalidArgumentException(
"Invalid object cache type \"$id\" requested. " .
152 "It is not present in \$wgObjectCaches." );
165 if ( !isset( $this->instances[$id] ) ) {
166 $this->instances[$id] = $this->newFromId( $id );
169 return $this->instances[$id];
190 $logger = $this->logger->getLogger( $params[
'loggroup'] ??
'objectcache' );
194 'keyspace' => $this->getDefaultKeyspace(),
196 'asyncHandler' => [ DeferredUpdates::class,
'addCallableUpdate' ],
197 'reportDupes' =>
true,
198 'stats' => $this->stats,
199 'telemetry' => $this->telemetry,
202 if ( isset( $params[
'factory'] ) ) {
203 $args = $params[
'args'] ?? [ $params ];
205 return $params[
'factory']( ...$args );
208 if ( !isset( $params[
'class'] ) ) {
209 throw new InvalidArgumentException(
210 'No "factory" nor "class" provided; got "' . print_r( $params,
true ) .
'"'
214 $class = $params[
'class'];
217 if ( is_a( $class, SqlBagOStuff::class,
true ) ) {
218 $this->prepareSqlBagOStuffFromParams( $params );
222 if ( is_subclass_of( $class, MemcachedBagOStuff::class ) ) {
223 $this->prepareMemcachedBagOStuffFromParams( $params );
227 if ( is_a( $class, MultiWriteBagOStuff::class,
true ) ) {
228 $this->prepareMultiWriteBagOStuffFromParams( $params );
231 return new $class( $params );
234 private function prepareSqlBagOStuffFromParams( array &$params ): void {
236 throw new InvalidArgumentException(
237 'globalKeyLB in $wgObjectCaches is no longer supported' );
239 if ( isset( $params[
'server'] ) && !isset( $params[
'servers'] ) ) {
241 unset( $params[
'server'] );
243 if ( isset( $params[
'servers'] ) ) {
245 foreach ( $params[
'servers'] as &$server ) {
246 if ( $server[
'type'] ===
'sqlite' && !isset( $server[
'dbDirectory'] ) ) {
247 $server[
'dbDirectory'] = $this->options->get( MainConfigNames::SQLiteDataDir );
250 } elseif ( isset( $params[
'cluster'] ) ) {
252 $dbLbFactory = $this->dbLoadBalancerFactory;
253 $params[
'loadBalancerCallback'] =
static function () use ( $cluster, $dbLbFactory ) {
254 return $dbLbFactory()->getExternalLB( $cluster );
256 $params += [
'dbDomain' => false ];
258 $dbLbFactory = $this->dbLoadBalancerFactory;
259 $params[
'loadBalancerCallback'] =
static function () use ( $dbLbFactory ) {
260 return $dbLbFactory()->getMainLb();
262 $params += [
'dbDomain' => false ];
264 $params += [
'writeBatchSize' => $this->options->get( MainConfigNames::UpdateRowsPerQuery ) ];
267 private function prepareMemcachedBagOStuffFromParams( array &$params ): void {
269 'servers' => $this->options->get( MainConfigNames::MemCachedServers ),
270 'persistent' => $this->options->get( MainConfigNames::MemCachedPersistent ),
271 'timeout' => $this->options->get( MainConfigNames::MemCachedTimeout ),
275 private function prepareMultiWriteBagOStuffFromParams( array &$params ): void {
278 '@phan-var array{caches:array[]} $params';
279 foreach ( $params[
'caches'] ?? [] as $i => $cacheInfo ) {
282 $params[
'caches'][$i] = $this->newFromParams( $cacheInfo );
308 $cache = $this->getInstance(
$fallback );
318 $this->instances = [];
325 private static function getLocalServerCacheClass() {
326 if ( self::$localServerCacheClass !==
null ) {
327 return self::$localServerCacheClass;
329 if ( function_exists(
'apcu_fetch' ) ) {
331 if ( PHP_SAPI !==
'cli' || ini_get(
'apc.enable_cli' ) ) {
332 return APCUBagOStuff::class;
337 return EmptyBagOStuff::class;
348 $this->options->get( MainConfigNames::MainCacheType ),
349 $this->options->get( MainConfigNames::MessageCacheType ),
350 $this->options->get( MainConfigNames::ParserCacheType )
352 foreach ( $candidates as $candidate ) {
356 $class = self::getLocalServerCacheClass();
357 if ( $class !== EmptyBagOStuff::class ) {
365 $services = MediaWikiServices::getInstance();
367 if ( $services->isServiceDisabled(
'DBLoadBalancer' ) ) {
370 } elseif ( $services->isStorageDisabled() ) {
401 'reportDupes' =>
false,
403 'keyspace' => $keyspace,
405 $class = self::getLocalServerCacheClass();
406 return new $class( $params );
422 $id = $this->getAnythingId();
423 return $this->isDatabaseId( $id );
426 if ( !isset( $this->options->get( MainConfigNames::ObjectCaches )[$id] ) ) {
429 $cache = $this->options->get( MainConfigNames::ObjectCaches )[$id];
430 if ( ( $cache[
'class'] ??
'' ) === SqlBagOStuff::class ) {
444 return $this->getInstance(
445 $this->options->get( MainConfigNames::MainCacheType )
451class_alias( ObjectCacheFactory::class,
'ObjectCacheFactory' );
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
if(!defined('MW_SETUP_CALLBACK'))
A class containing constants representing the names of configuration variables.
const UpdateRowsPerQuery
Name constant for the UpdateRowsPerQuery setting, for use with Config::get()
const MainCacheType
Name constant for the MainCacheType setting, for use with Config::get()
const MemCachedPersistent
Name constant for the MemCachedPersistent setting, for use with Config::get()
const MemCachedTimeout
Name constant for the MemCachedTimeout setting, for use with Config::get()
const ObjectCaches
Name constant for the ObjectCaches setting, for use with Config::get()
const MemCachedServers
Name constant for the MemCachedServers setting, for use with Config::get()
const MessageCacheType
Name constant for the MessageCacheType setting, for use with Config::get()
const SQLiteDataDir
Name constant for the SQLiteDataDir setting, for use with Config::get()
const CachePrefix
Name constant for the CachePrefix setting, for use with Config::get()
const ParserCacheType
Name constant for the ParserCacheType setting, for use with Config::get()