26 use InvalidArgumentException;
27 use UnexpectedValueException;
139 parent::__construct( $conf );
141 $this->hostsByName = $conf[
'hostsByName'] ?? [];
142 $this->sectionsByDB = $conf[
'sectionsByDB'];
143 $this->groupLoadsBySection = $conf[
'groupLoadsBySection'] ?? [];
144 foreach ( ( $conf[
'sectionLoads'] ?? [] ) as $section => $loadByHost ) {
145 $this->groupLoadsBySection[$section][ILoadBalancer::GROUP_GENERIC] = $loadByHost;
147 $this->groupLoadsByDB = $conf[
'groupLoadsByDB'] ?? [];
148 $this->externalLoads = $conf[
'externalLoads'] ?? [];
149 $this->serverTemplate = $conf[
'serverTemplate'] ?? [];
150 $this->externalTemplateOverrides = $conf[
'externalTemplateOverrides'] ?? [];
151 $this->templateOverridesBySection = $conf[
'templateOverridesBySection'] ?? [];
152 $this->templateOverridesByCluster = $conf[
'templateOverridesByCluster'] ?? [];
153 $this->masterTemplateOverrides = $conf[
'masterTemplateOverrides'] ?? [];
154 $this->templateOverridesByServer = $conf[
'templateOverridesByServer'] ?? [];
155 $this->readOnlyBySection = $conf[
'readOnlyBySection'] ?? [];
157 $this->loadMonitorClass = $conf[
'loadMonitorClass'] ?? LoadMonitor::class;
160 public function newMainLB( $domain =
false, $owner =
null ) {
162 if ( !isset( $this->groupLoadsBySection[$section][ILoadBalancer::GROUP_GENERIC] ) ) {
163 throw new UnexpectedValueException(
"Section '$section' has no hosts defined." );
166 $dbGroupLoads = $this->groupLoadsByDB[$this->
getDomainDatabase( $domain )] ?? [];
167 unset( $dbGroupLoads[ILoadBalancer::GROUP_GENERIC] );
171 $this->serverTemplate,
172 $this->templateOverridesBySection[$section] ?? []
174 array_merge( $this->groupLoadsBySection[$section], $dbGroupLoads ),
176 is_string( $this->readOnlyReason )
177 ? $this->readOnlyReason
178 : ( $this->readOnlyBySection[$section] ??
false ),
186 if ( !isset( $this->mainLBs[$section] ) ) {
190 return $this->mainLBs[$section];
194 if ( !isset( $this->externalLoads[$cluster] ) ) {
195 throw new InvalidArgumentException(
"Unknown cluster '$cluster'" );
200 $this->serverTemplate,
201 $this->externalTemplateOverrides,
202 $this->templateOverridesByCluster[$cluster] ?? []
204 [ ILoadBalancer::GROUP_GENERIC => $this->externalLoads[$cluster] ],
205 $this->readOnlyReason,
211 if ( !isset( $this->externalLBs[$cluster] ) ) {
212 $this->externalLBs[$cluster] =
216 return $this->externalLBs[$cluster];
221 foreach ( $this->sectionsByDB as $db => $section ) {
222 if ( !isset( $lbs[$section] ) ) {
223 $lbs[$section] = $this->
getMainLB( $db );
232 foreach ( $this->externalLoads as $cluster => $unused ) {
239 public function forEachLB( $callback, array $params = [] ) {
240 foreach ( $this->mainLBs as $lb ) {
241 $callback( $lb, ...$params );
243 foreach ( $this->externalLBs as $lb ) {
244 $callback( $lb, ...$params );
253 if ( $this->lastDomain === $domain ) {
258 $section = $this->sectionsByDB[$database] ?? self::CLUSTER_MAIN_DEFAULT;
259 $this->lastSection = $section;
260 $this->lastDomain = $domain;
279 'loadMonitor' => [
'class' => $this->loadMonitorClass ],
297 if ( !$groupLoads[ILoadBalancer::GROUP_GENERIC] ) {
298 throw new UnexpectedValueException(
"Empty generic load array; no master defined." );
303 $genericLoads = $groupLoads[ILoadBalancer::GROUP_GENERIC];
305 $genericLoads += array_fill_keys( array_keys( $groupLoadsByHost ), 0 );
308 foreach ( $genericLoads as $host => $load ) {
309 $servers[] = array_merge(
311 $servers ? [] : $this->masterTemplateOverrides,
312 $this->templateOverridesByServer[$host] ?? [],
314 'host' => $this->hostsByName[$host] ?? $host,
317 'groupLoads' => $groupLoadsByHost[$host] ?? []
333 foreach ( $groupLoads as $group => $loadByHost ) {
334 foreach ( $loadByHost as $host => $load ) {
335 $reindexed[$host][$group] = $load;
347 return ( $domain ===
false )
348 ? $this->localDomain->getDatabase()