X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Flibs%2Frdbms%2Floadbalancer%2FLoadBalancer.php;h=fe0c6228a1eba498ea3a1f1e399419fa1dd01384;hb=138298b397b308ad6e4bfc7088884d90e8ac1e37;hp=eabcbbdb4f6af43eee74a6184814cd1a7d4462f0;hpb=765370a6db20c95907abd9ed1b6d4a285638acb3;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php index eabcbbdb4f..fe0c6228a1 100644 --- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php @@ -38,10 +38,39 @@ use Exception; * @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) */ @@ -52,31 +81,24 @@ class LoadBalancer implements ILoadBalancer { 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; @@ -94,35 +116,19 @@ class LoadBalancer implements ILoadBalancer { 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; @@ -172,9 +178,7 @@ class LoadBalancer implements ILoadBalancer { : 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 = [ @@ -228,35 +232,27 @@ class LoadBalancer implements ILoadBalancer { } 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']; @@ -269,6 +265,8 @@ class LoadBalancer implements ILoadBalancer { $this->trxRoundStage = self::ROUND_ROLLBACK_CALLBACKS; } } + + $this->defaultGroup = $params['defaultGroup'] ?? null; } /** @@ -321,9 +319,7 @@ class LoadBalancer implements ILoadBalancer { 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 ); @@ -729,8 +725,11 @@ class LoadBalancer implements ILoadBalancer { } } + // 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() ); @@ -876,7 +875,7 @@ class LoadBalancer implements ILoadBalancer { $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 @@ -987,7 +986,7 @@ class LoadBalancer implements ILoadBalancer { $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 { @@ -1033,7 +1032,7 @@ class LoadBalancer implements ILoadBalancer { 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 ); } @@ -1106,7 +1105,7 @@ class LoadBalancer implements ILoadBalancer { $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 { @@ -1195,8 +1194,16 @@ class LoadBalancer implements ILoadBalancer { 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() { @@ -1297,7 +1304,7 @@ class LoadBalancer implements ILoadBalancer { 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 ) { @@ -1374,7 +1381,7 @@ class LoadBalancer implements ILoadBalancer { 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()}"; } } @@ -1727,8 +1734,7 @@ class LoadBalancer implements ILoadBalancer { 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 ); } } } @@ -1740,8 +1746,7 @@ class LoadBalancer implements ILoadBalancer { 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 ); } } } @@ -1754,8 +1759,7 @@ class LoadBalancer implements ILoadBalancer { continue; // skip master } foreach ( $serverConns as $conn ) { - $mergedParams = array_merge( [ $conn ], $params ); - call_user_func_array( $callback, $mergedParams ); + $callback( $conn, ...$params ); } } }