64 public const CONSTRUCTOR_OPTIONS = [
65 MainConfigNames::SQLiteDataDir,
66 MainConfigNames::UpdateRowsPerQuery,
67 MainConfigNames::MemCachedServers,
68 MainConfigNames::MemCachedPersistent,
69 MainConfigNames::MemCachedTimeout,
70 MainConfigNames::CachePrefix,
71 MainConfigNames::ObjectCaches,
72 MainConfigNames::MainCacheType,
79 private $instances = [];
80 private string $domainId;
82 private $dbLoadBalancerFactory;
88 callable $dbLoadBalancerFactory,
92 $this->options = $options;
93 $this->stats = $stats;
94 $this->logger = $loggerSpi;
95 $this->dbLoadBalancerFactory = $dbLoadBalancerFactory;
96 $this->domainId = $domainId;
108 private function getDefaultKeyspace(): string {
110 if ( is_string( $cachePrefix ) && $cachePrefix !==
'' ) {
114 return $this->domainId;
123 private function newFromId( $id ):
BagOStuff {
128 if ( !isset( $this->options->get( MainConfigNames::ObjectCaches )[$id] ) ) {
138 throw new InvalidArgumentException(
"Invalid object cache type \"$id\" requested. " .
139 "It is not present in \$wgObjectCaches." );
142 return $this->newFromParams( $this->options->get( MainConfigNames::ObjectCaches )[$id] );
152 if ( !isset( $this->instances[$id] ) ) {
153 $this->instances[$id] = $this->newFromId( $id );
156 return $this->instances[$id];
175 $logger = $this->logger->getLogger(
$params[
'loggroup'] ??
'objectcache' );
179 'keyspace' => $this->getDefaultKeyspace(),
180 'asyncHandler' => [ DeferredUpdates::class,
'addCallableUpdate' ],
181 'reportDupes' =>
true,
182 'stats' => $this->stats,
185 if ( isset(
$params[
'factory'] ) ) {
188 return call_user_func(
$params[
'factory'], ...$args );
191 if ( !isset(
$params[
'class'] ) ) {
192 throw new InvalidArgumentException(
193 'No "factory" nor "class" provided; got "' . print_r(
$params,
true ) .
'"'
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 );
213 if ( is_a( $class, RESTBagOStuff::class,
true ) ) {
214 $this->prepareRESTBagOStuffFromParams(
$params );
220 private function prepareSqlBagOStuffFromParams( array &
$params ): void {
222 throw new InvalidArgumentException(
223 'globalKeyLB in $wgObjectCaches is no longer supported' );
225 if ( isset(
$params[
'server'] ) && !isset(
$params[
'servers'] ) ) {
229 if ( isset(
$params[
'servers'] ) ) {
231 foreach (
$params[
'servers'] as &$server ) {
232 if ( $server[
'type'] ===
'sqlite' && !isset( $server[
'dbDirectory'] ) ) {
233 $server[
'dbDirectory'] = $this->options->get( MainConfigNames::SQLiteDataDir );
236 } elseif ( isset(
$params[
'cluster'] ) ) {
238 $dbLbFactory = $this->dbLoadBalancerFactory;
239 $params[
'loadBalancerCallback'] =
static function () use ( $cluster, $dbLbFactory ) {
240 return $dbLbFactory()->getExternalLB( $cluster );
242 $params += [
'dbDomain' => false ];
244 $dbLbFactory = $this->dbLoadBalancerFactory;
245 $params[
'loadBalancerCallback'] =
static function () use ( $dbLbFactory ) {
246 return $dbLbFactory()->getMainLb();
248 $params += [
'dbDomain' => false ];
250 $params += [
'writeBatchSize' => $this->options->get( MainConfigNames::UpdateRowsPerQuery ) ];
253 private function prepareMemcachedBagOStuffFromParams( array &
$params ): void {
256 'persistent' => $this->options->get(
MainConfigNames::MemCachedPersistent ),
261 private function prepareMultiWriteBagOStuffFromParams( array &
$params ): void {
264 '@phan-var array{caches:array[]} $params';
265 foreach (
$params[
'caches'] ?? [] as $i => $cacheInfo ) {
268 $params[
'caches'][$i] = $this->newFromParams( $cacheInfo );
272 private function prepareRESTBagOStuffFromParams( array &
$params ): void {
298 $cache = $this->getInstance(
$fallback );
308 $this->instances = [];
319 if ( !defined(
'MW_PHPUNIT_TEST' ) ) {
320 throw new LogicException( __METHOD__ .
' can not be called outside of tests' );
322 $this->instances[$cacheId] = $cache;