26use InvalidArgumentException;
28use UnexpectedValueException;
114 parent::__construct( $conf );
116 $this->hostsByServerName = $conf[
'hostsByName'] ?? [];
117 $this->sectionsByDB = $conf[
'sectionsByDB'];
118 $this->groupLoadsBySection = $conf[
'groupLoadsBySection'] ?? [];
119 foreach ( ( $conf[
'sectionLoads'] ?? [] ) as $section => $loadsByServerName ) {
122 $this->groupLoadsByDB = $conf[
'groupLoadsByDB'] ?? [];
123 $this->externalLoadsByCluster = $conf[
'externalLoads'] ?? [];
124 $this->serverTemplate = $conf[
'serverTemplate'] ?? [];
125 $this->externalTemplateOverrides = $conf[
'externalTemplateOverrides'] ?? [];
126 $this->templateOverridesBySection = $conf[
'templateOverridesBySection'] ?? [];
127 $this->templateOverridesByCluster = $conf[
'templateOverridesByCluster'] ?? [];
128 $this->masterTemplateOverrides = $conf[
'masterTemplateOverrides'] ?? [];
129 $this->templateOverridesByServer = $conf[
'templateOverridesByServer'] ?? [];
130 $this->readOnlyBySection = $conf[
'readOnlyBySection'] ?? [];
132 if ( isset( $conf[
'loadMonitor'] ) ) {
133 $this->loadMonitorConfig = $conf[
'loadMonitor'];
134 } elseif ( isset( $conf[
'loadMonitorClass'] ) ) {
135 $this->loadMonitorConfig = [
'class' => $conf[
'loadMonitorClass'] ];
137 $this->loadMonitorConfig = [
'class' => LoadMonitor::class ];
140 foreach ( array_keys( $this->externalLoadsByCluster ) as $cluster ) {
141 if ( isset( $this->groupLoadsBySection[$cluster] ) ) {
142 throw new LogicException(
143 "External cluster '$cluster' has the same name as a main section/cluster"
151 $database = $domainInstance->getDatabase();
155 throw new UnexpectedValueException(
"Section '$section' has no hosts defined." );
158 $dbGroupLoads = $this->groupLoadsByDB[$database] ?? [];
163 $this->serverTemplate,
164 $this->templateOverridesBySection[$section] ?? []
166 array_merge( $this->groupLoadsBySection[$section], $dbGroupLoads ),
168 is_string( $this->readOnlyReason )
169 ? $this->readOnlyReason
170 : ( $this->readOnlyBySection[$section] ?? false ),
176 $domainInstance = $this->resolveDomainInstance( $domain );
177 $section = $this->getSectionFromDatabase( $domainInstance->getDatabase() );
179 if ( !isset( $this->mainLBs[$section] ) ) {
180 $this->mainLBs[$section] = $this->newMainLB( $domain, $this->getOwnershipId() );
183 return $this->mainLBs[$section];
187 if ( !isset( $this->externalLoadsByCluster[$cluster] ) ) {
188 throw new InvalidArgumentException(
"Unknown cluster '$cluster'" );
190 return $this->newLoadBalancer(
193 $this->serverTemplate,
194 $this->externalTemplateOverrides,
195 $this->templateOverridesByCluster[$cluster] ?? []
197 [ ILoadBalancer::GROUP_GENERIC => $this->externalLoadsByCluster[$cluster] ],
198 $this->readOnlyReason,
204 if ( !isset( $this->externalLBs[$cluster] ) ) {
205 $this->externalLBs[$cluster] = $this->newExternalLB(
207 $this->getOwnershipId()
211 return $this->externalLBs[$cluster];
216 foreach ( $this->sectionsByDB as $db => $section ) {
217 if ( !isset( $lbs[$section] ) ) {
218 $lbs[$section] = $this->getMainLB( $db );
227 foreach ( $this->externalLoadsByCluster as $cluster => $unused ) {
228 $lbs[$cluster] = $this->getExternalLB( $cluster );
234 public function forEachLB( $callback, array $params = [] ) {
235 foreach ( $this->mainLBs as $lb ) {
236 $callback( $lb, ...$params );
238 foreach ( $this->externalLBs as $lb ) {
239 $callback( $lb, ...$params );
255 array $serverTemplate,
261 $this->baseLoadBalancerParams( $owner ),
263 'servers' => $this->makeServerConfigArrays( $serverTemplate, $groupLoads ),
264 'loadMonitor' => $this->loadMonitorConfig,
265 'readOnlyReason' => $readOnlyReason,
266 'clusterName' => $clusterName
269 $this->initLoadBalancer( $lb );
283 if ( !$groupLoads[ILoadBalancer::GROUP_GENERIC] ) {
284 throw new UnexpectedValueException(
"Empty generic load array; no primary DB defined." );
286 $groupLoadsByServerName = $this->reindexGroupLoadsByServerName( $groupLoads );
288 $genericLoads = $groupLoads[ILoadBalancer::GROUP_GENERIC];
290 $genericLoads += array_fill_keys( array_keys( $groupLoadsByServerName ), 0 );
292 foreach ( $genericLoads as $serverName => $load ) {
293 $servers[] = array_merge(
295 $servers ? [] : $this->masterTemplateOverrides,
296 $this->templateOverridesByServer[$serverName] ?? [],
298 'host' => $this->hostsByServerName[$serverName] ?? $serverName,
299 'serverName' => $serverName,
301 'groupLoads' => $groupLoadsByServerName[$serverName] ?? []
316 $groupLoadsByServerName = [];
317 foreach ( $groupLoads as $group => $loadByServerName ) {
318 foreach ( $loadByServerName as $serverName => $load ) {
319 $groupLoadsByServerName[$serverName][$group] = $load;
323 return $groupLoadsByServerName;
331 return $this->sectionsByDB[$database] ?? self::CLUSTER_MAIN_DEFAULT;
if(ini_get('mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.