* @ingroup Database
*/
class LoadBalancer implements ILoadBalancer {
- /** @var array[] Map of (server index => server config array) */
- private $servers;
+ /** @var ILoadMonitor */
+ private $loadMonitor;
+ /** @var callable|null Callback to run before the first connection attempt */
+ private $chronologyCallback;
+ /** @var BagOStuff */
+ private $srvCache;
+ /** @var WANObjectCache */
+ private $wanCache;
+ /** @var object|string Class name or object With profileIn/profileOut methods */
+ private $profiler;
+ /** @var TransactionProfiler */
+ private $trxProfiler;
+ /** @var LoggerInterface */
+ private $replLogger;
+ /** @var LoggerInterface */
+ private $connLogger;
+ /** @var LoggerInterface */
+ private $queryLogger;
+ /** @var LoggerInterface */
+ private $perfLogger;
+ /** @var callable Exception logger */
+ private $errorLogger;
+ /** @var callable Deprecation logger */
+ private $deprecationLogger;
+
+ /** @var DatabaseDomain Local Domain ID and default for selectDB() calls */
+ private $localDomain;
+
/** @var Database[][][] Map of (connection category => server index => IDatabase[]) */
private $conns;
+
+ /** @var array[] Map of (server index => server config array) */
+ private $servers;
/** @var float[] Map of (server index => weight) */
private $loads;
/** @var array[] Map of (group => server index => weight) */
private $waitTimeout;
/** @var array The LoadMonitor configuration */
private $loadMonitorConfig;
+ /** @var string Alternate ID string for the domain instead of DatabaseDomain::getId() */
+ private $localDomainIdAlias;
+ /** @var int */
+ private $maxLag = self::MAX_LAG_DEFAULT;
+
+ /** @var string Current server name */
+ private $hostname;
+ /** @var bool Whether this PHP instance is for a CLI script */
+ private $cliMode;
+ /** @var string Agent name for query profiling */
+ private $agent;
+
/** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
private $tableAliases = [];
/** @var string[] Map of (index alias => index) */
private $indexAliases = [];
-
- /** @var ILoadMonitor */
- private $loadMonitor;
- /** @var callable|null Callback to run before the first connection attempt */
- private $chronologyCallback;
- /** @var BagOStuff */
- private $srvCache;
- /** @var WANObjectCache */
- private $wanCache;
- /** @var object|string Class name or object With profileIn/profileOut methods */
- protected $profiler;
- /** @var TransactionProfiler */
- protected $trxProfiler;
- /** @var LoggerInterface */
- protected $replLogger;
- /** @var LoggerInterface */
- protected $connLogger;
- /** @var LoggerInterface */
- protected $queryLogger;
- /** @var LoggerInterface */
- protected $perfLogger;
+ /** @var array[] Map of (name => callable) */
+ private $trxRecurringCallbacks = [];
/** @var Database DB connection object that caused a problem */
private $errorConnection;
private $readOnlyReason = false;
/** @var int Total connections opened */
private $connsOpened = 0;
- /** @var string|bool String if a requested DBO_TRX transaction round is active */
- private $trxRoundId = false;
- /** @var array[] Map of (name => callable) */
- private $trxRecurringCallbacks = [];
- /** @var DatabaseDomain Local Domain ID and default for selectDB() calls */
- private $localDomain;
- /** @var string Alternate ID string for the domain instead of DatabaseDomain::getId() */
- private $localDomainIdAlias;
- /** @var string Current server name */
- private $host;
- /** @var bool Whether this PHP instance is for a CLI script */
- protected $cliMode;
- /** @var string Agent name for query profiling */
- protected $agent;
-
- /** @var callable Exception logger */
- private $errorLogger;
- /** @var callable Deprecation logger */
- private $deprecationLogger;
-
/** @var bool */
private $disabled = false;
/** @var bool Whether any connection has been attempted yet */
private $connectionAttempted = false;
- /** @var int */
- private $maxLag = self::MAX_LAG_DEFAULT;
+
+ /** @var string|bool String if a requested DBO_TRX transaction round is active */
+ private $trxRoundId = false;
/** @var string Stage of the current transaction round in the transaction round life-cycle */
private $trxRoundStage = self::ROUND_CURSORY;
+ /** @var string|null */
+ private $defaultGroup = null;
+
/** @var int Warn when this many connection are held */
const CONN_HELD_WARN_THRESHOLD = 10;
: DatabaseDomain::newUnspecified();
$this->setLocalDomain( $localDomain );
- $this->waitTimeout = isset( $params['waitTimeout'] )
- ? $params['waitTimeout']
- : self::MAX_WAIT_DEFAULT;
+ $this->waitTimeout = $params['waitTimeout'] ?? self::MAX_WAIT_DEFAULT;
$this->readIndex = -1;
$this->conns = [
} else {
$this->wanCache = WANObjectCache::newEmpty();
}
- $this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
+ $this->profiler = $params['profiler'] ?? null;
if ( isset( $params['trxProfiler'] ) ) {
$this->trxProfiler = $params['trxProfiler'];
} else {
$this->trxProfiler = new TransactionProfiler();
}
- $this->errorLogger = isset( $params['errorLogger'] )
- ? $params['errorLogger']
- : function ( Exception $e ) {
- trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
- };
- $this->deprecationLogger = isset( $params['deprecationLogger'] )
- ? $params['deprecationLogger']
- : function ( $msg ) {
- trigger_error( $msg, E_USER_DEPRECATED );
- };
+ $this->errorLogger = $params['errorLogger'] ?? function ( Exception $e ) {
+ trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
+ };
+ $this->deprecationLogger = $params['deprecationLogger'] ?? function ( $msg ) {
+ trigger_error( $msg, E_USER_DEPRECATED );
+ };
foreach ( [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ] as $key ) {
- $this->$key = isset( $params[$key] ) ? $params[$key] : new NullLogger();
+ $this->$key = $params[$key] ?? new NullLogger();
}
- $this->host = isset( $params['hostname'] )
- ? $params['hostname']
- : ( gethostname() ?: 'unknown' );
- $this->cliMode = isset( $params['cliMode'] )
- ? $params['cliMode']
- : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
- $this->agent = isset( $params['agent'] ) ? $params['agent'] : '';
+ $this->hostname = $params['hostname'] ?? ( gethostname() ?: 'unknown' );
+ $this->cliMode = $params['cliMode'] ?? ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
+ $this->agent = $params['agent'] ?? '';
if ( isset( $params['chronologyCallback'] ) ) {
$this->chronologyCallback = $params['chronologyCallback'];
$this->trxRoundStage = self::ROUND_ROLLBACK_CALLBACKS;
}
}
+
+ $this->defaultGroup = $params['defaultGroup'] ?? null;
}
/**
foreach ( $lags as $i => $lag ) {
if ( $i != 0 ) {
# How much lag this server nominally is allowed to have
- $maxServerLag = isset( $this->servers[$i]['max lag'] )
- ? $this->servers[$i]['max lag']
- : $this->maxLag; // default
+ $maxServerLag = $this->servers[$i]['max lag'] ?? $this->maxLag; // default
# Constrain that futher by $maxLag argument
$maxServerLag = min( $maxServerLag, $maxLag );
}
}
+ // Check one "group" per default: the generic pool
+ $defaultGroups = $this->defaultGroup ? [ $this->defaultGroup ] : [ false ];
+
$groups = ( $groups === false || $groups === [] )
- ? [ false ] // check one "group": the generic pool
+ ? $defaultGroups
: (array)$groups;
$masterOnly = ( $i == self::DB_MASTER || $i == $this->getWriterIndex() );
$this->connLogger->debug( __METHOD__ . ': calling initLB() before first connection.' );
// Load any "waitFor" positions before connecting so that doWait() is triggered
$this->connectionAttempted = true;
- call_user_func( $this->chronologyCallback, $this );
+ ( $this->chronologyCallback )( $this );
}
// Check if an auto-commit connection is being requested. If so, it will not reuse the
$oldDomain = key( $this->conns[$connFreeKey][$i] );
if ( strlen( $dbName ) && !$conn->selectDB( $dbName ) ) {
$this->lastError = "Error selecting database '$dbName' on server " .
- $conn->getServer() . " from client host {$this->host}";
+ $conn->getServer() . " from client host {$this->hostname}";
$this->errorConnection = $conn;
$conn = false;
} else {
public function getServerAttributes( $i ) {
return Database::attributesFromType(
$this->getServerType( $i ),
- isset( $this->servers[$i]['driver'] ) ? $this->servers[$i]['driver'] : null
+ $this->servers[$i]['driver'] ?? null
);
}
$server['agent'] = $this->agent;
// Use DBO_DEFAULT flags by default for LoadBalancer managed databases. Assume that the
// application calls LoadBalancer::commitMasterChanges() before the PHP script completes.
- $server['flags'] = isset( $server['flags'] ) ? $server['flags'] : IDatabase::DBO_DEFAULT;
+ $server['flags'] = $server['flags'] ?? IDatabase::DBO_DEFAULT;
// Create a live connection object
try {
return ( $name != '' ) ? $name : 'localhost';
}
+ public function getServerInfo( $i ) {
+ if ( isset( $this->servers[$i] ) ) {
+ return $this->servers[$i];
+ } else {
+ return false;
+ }
+ }
+
public function getServerType( $i ) {
- return isset( $this->servers[$i]['type'] ) ? $this->servers[$i]['type'] : 'unknown';
+ return $this->servers[$i]['type'] ?? 'unknown';
}
public function getMasterPos() {
public function approveMasterChanges( array $options ) {
$this->assertTransactionRoundStage( self::ROUND_FINALIZED );
- $limit = isset( $options['maxWriteDuration'] ) ? $options['maxWriteDuration'] : 0;
+ $limit = $options['maxWriteDuration'] ?? 0;
$this->trxRoundStage = self::ROUND_ERROR; // "failed" until proven otherwise
$this->forEachOpenMasterConnection( function ( IDatabase $conn ) use ( $limit ) {
try {
$conn->commit( $fname, $conn::FLUSHING_ALL_PEERS );
} catch ( DBError $e ) {
- call_user_func( $this->errorLogger, $e );
+ ( $this->errorLogger )( $e );
$failures[] = "{$conn->getServer()}: {$e->getMessage()}";
}
}
foreach ( $this->conns as $connsByServer ) {
foreach ( $connsByServer as $serverConns ) {
foreach ( $serverConns as $conn ) {
- $mergedParams = array_merge( [ $conn ], $params );
- call_user_func_array( $callback, $mergedParams );
+ $callback( $conn, ...$params );
}
}
}
if ( isset( $connsByServer[$masterIndex] ) ) {
/** @var IDatabase $conn */
foreach ( $connsByServer[$masterIndex] as $conn ) {
- $mergedParams = array_merge( [ $conn ], $params );
- call_user_func_array( $callback, $mergedParams );
+ $callback( $conn, ...$params );
}
}
}
continue; // skip master
}
foreach ( $serverConns as $conn ) {
- $mergedParams = array_merge( [ $conn ], $params );
- call_user_func_array( $callback, $mergedParams );
+ $callback( $conn, ...$params );
}
}
}