9use InvalidArgumentException;
83 private $instances = [];
84 private string $domainId;
86 private $dbLoadBalancerFactory;
97 callable $dbLoadBalancerFactory,
102 $this->options = $options;
103 $this->stats = $stats;
104 $this->logger = $loggerSpi;
105 $this->dbLoadBalancerFactory = $dbLoadBalancerFactory;
106 $this->domainId = $domainId;
107 $this->telemetry = $telemetry;
116 private function newFromId( $id ):
BagOStuff {
126 return new HashBagOStuff();
129 } elseif ( $id ===
'wincache' ) {
130 wfDeprecated( __METHOD__ .
' with cache ID "wincache"',
'1.43' );
134 throw new InvalidArgumentException(
"Invalid object cache type \"$id\" requested. " .
135 "It is not present in \$wgObjectCaches." );
148 if ( !isset( $this->instances[$id] ) ) {
149 $this->instances[$id] = $this->newFromId( $id );
152 return $this->instances[$id];
173 $logger = $this->logger->getLogger( $params[
'loggroup'] ??
'objectcache' );
177 'keyspace' => $this->domainId,
179 'asyncHandler' => [ DeferredUpdates::class,
'addCallableUpdate' ],
180 'reportDupes' =>
true,
181 'stats' => $this->stats,
182 'telemetry' => $this->telemetry,
185 if ( isset( $params[
'factory'] ) ) {
186 $args = $params[
'args'] ?? [ $params ];
188 return $params[
'factory']( ...$args );
191 if ( !isset( $params[
'class'] ) ) {
192 throw new InvalidArgumentException(
193 'No "factory" nor "class" provided; got "' . print_r( $params,
true ) .
'"'
197 $class = $params[
'class'];
200 if ( is_a( $class, SqlBagOStuff::class,
true ) ) {
201 $this->prepareSqlBagOStuffFromParams( $params );
205 if ( is_subclass_of( $class, MemcachedBagOStuff::class ) ) {
206 $this->prepareMemcachedBagOStuffFromParams( $params );
210 if ( is_a( $class, MultiWriteBagOStuff::class,
true ) ) {
211 $this->prepareMultiWriteBagOStuffFromParams( $params );
214 return new $class( $params );
217 private function prepareSqlBagOStuffFromParams( array &$params ): void {
219 throw new InvalidArgumentException(
220 'globalKeyLB in $wgObjectCaches is no longer supported' );
222 if ( isset( $params[
'server'] ) && !isset( $params[
'servers'] ) ) {
224 unset( $params[
'server'] );
226 if ( isset( $params[
'servers'] ) ) {
228 foreach ( $params[
'servers'] as &$server ) {
229 if ( $server[
'type'] ===
'sqlite' && !isset( $server[
'dbDirectory'] ) ) {
230 $server[
'dbDirectory'] = $this->options->get( MainConfigNames::SQLiteDataDir );
233 } elseif ( isset( $params[
'cluster'] ) ) {
235 $dbLbFactory = $this->dbLoadBalancerFactory;
236 $params[
'loadBalancerCallback'] =
static function () use ( $cluster, $dbLbFactory ) {
237 return $dbLbFactory()->getExternalLB( $cluster );
239 $params += [
'dbDomain' => false ];
241 $dbLbFactory = $this->dbLoadBalancerFactory;
242 $params[
'loadBalancerCallback'] =
static function () use ( $dbLbFactory ) {
243 return $dbLbFactory()->getMainLb();
245 $params += [
'dbDomain' => false ];
247 $params += [
'writeBatchSize' => $this->options->get( MainConfigNames::UpdateRowsPerQuery ) ];
250 private function prepareMemcachedBagOStuffFromParams( array &$params ): void {
252 'servers' => $this->options->get( MainConfigNames::MemCachedServers ),
253 'persistent' => $this->options->get( MainConfigNames::MemCachedPersistent ),
254 'timeout' => $this->options->get( MainConfigNames::MemCachedTimeout ),
258 private function prepareMultiWriteBagOStuffFromParams( array &$params ): void {
261 '@phan-var array{caches:array[]} $params';
262 foreach ( $params[
'caches'] ?? [] as $i => $cacheInfo ) {
265 $params[
'caches'][$i] = $this->newFromParams( $cacheInfo );
291 $cache = $this->getInstance(
$fallback );
301 $this->instances = [];
308 private static function getLocalServerCacheClass() {
309 if ( self::$localServerCacheClass !==
null ) {
310 return self::$localServerCacheClass;
312 if ( function_exists(
'apcu_fetch' ) ) {
314 if ( PHP_SAPI !==
'cli' || ini_get(
'apc.enable_cli' ) ) {
315 return APCUBagOStuff::class;
319 return EmptyBagOStuff::class;
330 $this->options->get( MainConfigNames::MainCacheType ),
331 $this->options->get( MainConfigNames::MessageCacheType ),
332 $this->options->get( MainConfigNames::ParserCacheType )
334 foreach ( $candidates as $candidate ) {
338 $class = self::getLocalServerCacheClass();
339 if ( $class !== EmptyBagOStuff::class ) {
347 $services = MediaWikiServices::getInstance();
349 if ( $services->isServiceDisabled(
'DBLoadBalancer' ) ) {
352 } elseif ( $services->isStorageDisabled() ) {
383 'reportDupes' =>
false,
385 'keyspace' => $keyspace,
387 $class = self::getLocalServerCacheClass();
388 return new $class( $params );
404 $id = $this->getAnythingId();
405 return $this->isDatabaseId( $id );
408 if ( !isset( $this->options->get( MainConfigNames::ObjectCaches )[$id] ) ) {
411 $cache = $this->options->get( MainConfigNames::ObjectCaches )[$id];
412 if ( ( $cache[
'class'] ??
'' ) === SqlBagOStuff::class ) {
426 return $this->getInstance(
427 $this->options->get( MainConfigNames::MainCacheType )
433class_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 ParserCacheType
Name constant for the ParserCacheType setting, for use with Config::get()