rdbms: add "loadMonitor" parameter to LBFactoryMulti/LBFactorySimple

This allows full configuration of the LoadMonitor, not just setting
the class name like loadMonitorClass allows. Deprecate the later.

Also fix obsolete LoadBalancer constructor documentation and
standardize the style of LBFactoryMulti::__construct() comments.

Change-Id: Icfdc0d6bbf227dce56e65ad679b93ce3f604e9f7
This commit is contained in:
Aaron Schulz 2020-03-27 20:18:05 -07:00
parent 7c4a3f8aae
commit fcfea80fa3
5 changed files with 69 additions and 74 deletions

View file

@ -39,31 +39,31 @@ class LBFactoryMulti extends LBFactory {
private $externalLBs = [];
/** @var string[] Map of (hostname => IP address) */
private $hostsByName = [];
private $hostsByName;
/** @var string[] Map of (database name => section name) */
private $sectionsByDB = [];
private $sectionsByDB;
/** @var int[][][] Map of (section => group => host => load ratio) */
private $groupLoadsBySection = [];
private $groupLoadsBySection;
/** @var int[][][] Map of (database => group => host => load ratio) */
private $groupLoadsByDB = [];
private $groupLoadsByDB;
/** @var int[][] Map of (cluster => host => load ratio) */
private $externalLoads = [];
private $externalLoads;
/** @var array Server config map ("host", "hostName", "load", and "groupLoads" are ignored) */
private $serverTemplate = [];
private $serverTemplate;
/** @var array Server config map overriding "serverTemplate" for external storage */
private $externalTemplateOverrides = [];
private $externalTemplateOverrides;
/** @var array[] Map of (section => server config map overrides) */
private $templateOverridesBySection = [];
private $templateOverridesBySection;
/** @var array[] Map of (cluster => server config map overrides) for external storage */
private $templateOverridesByCluster = [];
private $templateOverridesByCluster;
/** @var array Server config override map for all main and external master servers */
private $masterTemplateOverrides = [];
private $masterTemplateOverrides;
/** @var array[] Map of (host => server config map overrides) for main and external servers */
private $templateOverridesByServer = [];
private $templateOverridesByServer;
/** @var string[]|bool[] A map of section name to read-only message */
private $readOnlyBySection = [];
/** @var string LoadMonitor class to use within LoadBalancer instances */
private $loadMonitorClass = LoadMonitor::class;
private $readOnlyBySection;
/** @var array Configuration for the LoadMonitor to use within LoadBalancer instances */
private $loadMonitorConfig;
/**
* Template override precedence (highest => lowest):
@ -82,52 +82,33 @@ class LBFactoryMulti extends LBFactory {
*
* @see LBFactory::__construct()
* @param array $conf Additional parameters include:
* - hostsByName Optional (hostname => IP address) map.
* - sectionsByDB Optional map of (database => section name).
* For example:
* [
* 'DEFAULT' => 'section1',
* 'database1' => 'section2'
* ]
* - sectionLoads Optional map of (section => host => load ratio); the first
* host in each section is the master server for that section.
* For example:
* [
* 'dbmaser' => 0,
* 'dbreplica1' => 100,
* 'dbreplica2' => 100
* ]
* - groupLoadsBySection Optional map of (section => group => host => load ratio);
* any ILoadBalancer::GROUP_GENERIC group will be ignored.
* For example:
* [
* 'section1' => [
* 'group1' => [
* 'dbreplica3 => 100,
* 'dbreplica4' => 100
* ]
* ]
* ]
* - groupLoadsByDB Optional (database => group => host => load ratio) map.
* - externalLoads Optional (cluster => host => load ratio) map.
* - serverTemplate server config map for Database::factory().
* Note that "host", "hostName" and "load" entries will be
* overridden by "groupLoadsBySection" and "hostsByName".
* - externalTemplateOverrides Optional server config map overrides for external
* stores; respects the override precedence described above.
* - templateOverridesBySection Optional (section => server config map overrides) map;
* respects the override precedence described above.
* - templateOverridesByCluster Optional (external cluster => server config map overrides)
* map; respects the override precedence described above.
* - masterTemplateOverrides Optional server config map overrides for masters;
* respects the override precedence described above.
* - templateOverridesByServer Optional (host => server config map overrides) map;
* respects the override precedence described above
* and applies to both core and external storage.
* - loadMonitorClass Name of the LoadMonitor class to always use. [optional]
* - readOnlyBySection Optional map of (section name => message text or false).
* String values make sections read only, whereas anything
* else does not restrict read/write mode.
* - hostsByName: map of (hostname => IP address). [optional]
* - sectionsByDB: map of (database => section name). The database name "DEFAULT" is
* interpeted as a catch-all for all databases not otherwise mentioned. [optional]
* - sectionLoads: map of (section => host => load ratio); the first host listed in
* each section is the master server for that section. [optional]
* - groupLoadsBySection: map of (section => group => host => group load ratio).
* Any ILoadBalancer::GROUP_GENERIC group will be ignored. [optional]
* - groupLoadsByDB: map of (database => group => host => load ratio) map. [optional]
* - externalLoads: map of (cluster => host => load ratio) map. [optional]
* - serverTemplate: server config map for Database::factory().
* Note that "host", "hostName" and "load" entries will be overridden by
* "groupLoadsBySection" and "hostsByName". [optional]
* - externalTemplateOverrides: server config map overrides for external stores;
* respects the override precedence described above. [optional]
* - templateOverridesBySection: map of (section => server config map overrides);
* respects the override precedence described above. [optional]
* - templateOverridesByCluster: map of (external cluster => server config map overrides);
* respects the override precedence described above. [optional]
* - masterTemplateOverrides: server config map overrides for masters;
* respects the override precedence described above. [optional]
* - templateOverridesByServer: map of (host => server config map overrides);
* respects the override precedence described above and applies to both core
* and external storage. [optional]
* - loadMonitor: LoadMonitor::__construct() parameters with "class" field. [optional]
* - readOnlyBySection: map of (section name => message text or false).
* String values make sections read only, whereas anything else does not
* restrict read/write mode. [optional]
*/
public function __construct( array $conf ) {
parent::__construct( $conf );
@ -148,7 +129,13 @@ class LBFactoryMulti extends LBFactory {
$this->templateOverridesByServer = $conf['templateOverridesByServer'] ?? [];
$this->readOnlyBySection = $conf['readOnlyBySection'] ?? [];
$this->loadMonitorClass = $conf['loadMonitorClass'] ?? LoadMonitor::class;
if ( isset( $conf['loadMonitor'] ) ) {
$this->loadMonitorConfig = $conf['loadMonitor'];
} elseif ( isset( $conf['loadMonitorClass'] ) ) { // b/c
$this->loadMonitorConfig = [ 'class' => $conf['loadMonitorClass'] ];
} else {
$this->loadMonitorConfig = [ 'class' => LoadMonitor::class ];
}
}
public function newMainLB( $domain = false, $owner = null ) {
@ -253,7 +240,7 @@ class LBFactoryMulti extends LBFactory {
$this->baseLoadBalancerParams( $owner ),
[
'servers' => $this->makeServerConfigArrays( $serverTemplate, $groupLoads ),
'loadMonitor' => [ 'class' => $this->loadMonitorClass ],
'loadMonitor' => $this->loadMonitorConfig,
'readOnlyReason' => $readOnlyReason
]
) );

View file

@ -34,14 +34,14 @@ class LBFactorySimple extends LBFactory {
/** @var LoadBalancer[] */
private $externalLBs = [];
/** @var array Configuration for the LoadMonitor to use within LoadBalancer instances */
private $loadMonitorConfig;
/** @var array[] Map of (server index => server config map) */
private $mainServers = [];
/** @var array[][] Map of (cluster => server index => server config map) */
private $externalServersByCluster = [];
/** @var string */
private $loadMonitorClass;
/**
* @see LBFactory::__construct()
* @param array $conf Additional parameters include:
@ -53,6 +53,7 @@ class LBFactorySimple extends LBFactory {
* replication sync checks (intended for archive servers with unchanging data).
* - externalClusters : map of cluster names to server arrays. The servers arrays have the
* same format as "servers" above.
* - loadMonitor: LoadMonitor::__construct() parameters with "class" field. [optional]
*/
public function __construct( array $conf ) {
parent::__construct( $conf );
@ -63,7 +64,14 @@ class LBFactorySimple extends LBFactory {
$this->externalServersByCluster[$cluster][$index] = $server;
}
}
$this->loadMonitorClass = $conf['loadMonitorClass'] ?? LoadMonitor::class;
if ( isset( $conf['loadMonitor'] ) ) {
$this->loadMonitorConfig = $conf['loadMonitor'];
} elseif ( isset( $conf['loadMonitorClass'] ) ) { // b/c
$this->loadMonitorConfig = [ 'class' => $conf['loadMonitorClass'] ];
} else {
$this->loadMonitorConfig = [ 'class' => LoadMonitor::class ];
}
}
public function newMainLB( $domain = false, $owner = null ) {
@ -112,7 +120,7 @@ class LBFactorySimple extends LBFactory {
$this->baseLoadBalancerParams( $owner ),
[
'servers' => $servers,
'loadMonitor' => [ 'class' => $this->loadMonitorClass ],
'loadMonitor' => $this->loadMonitorConfig,
]
) );
$this->initLoadBalancer( $lb );

View file

@ -109,7 +109,7 @@ interface ILoadBalancer {
* @param array $params Parameter map with keys:
* - servers : List of server info structures
* - localDomain: A DatabaseDomain or domain ID string
* - loadMonitor : Name of a class used to fetch server lag and load
* - loadMonitor : LoadMonitor::__construct() parameters with "class" field. [optional]
* - readOnlyReason : Reason the master DB is read-only if so [optional]
* - waitTimeout : Maximum time to wait for replicas for consistency [optional]
* - maxLag: Try to avoid DB replicas with lag above this many seconds [optional]

View file

@ -107,7 +107,7 @@ class LBFactoryTest extends MediaWikiTestCase {
$factory = new LBFactorySimple( [
'servers' => $servers,
'loadMonitorClass' => LoadMonitorNull::class
'loadMonitor' => [ 'class' => LoadMonitorNull::class ],
] );
$lb = $factory->getMainLB();
@ -246,7 +246,7 @@ class LBFactoryTest extends MediaWikiTestCase {
'test-db3' => $wgDBserver,
'test-db4' => $wgDBserver
],
'loadMonitorClass' => LoadMonitorNull::class
'loadMonitor' => [ 'class' => LoadMonitorNull::class ],
] );
}
@ -412,7 +412,7 @@ class LBFactoryTest extends MediaWikiTestCase {
'hostsByName' => [
'test-db1' => $wgDBserver,
],
'loadMonitorClass' => LoadMonitorNull::class,
'loadMonitor' => [ 'class' => LoadMonitorNull::class ],
'localDomain' => new DatabaseDomain( $wgDBname, null, $wgDBprefix ),
'agent' => 'MW-UNIT-TESTS'
] );

View file

@ -327,7 +327,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
'servers' => $servers,
'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() ),
'queryLogger' => MediaWiki\Logger\LoggerFactory::getInstance( 'DBQuery' ),
'loadMonitorClass' => LoadMonitorNull::class
'loadMonitor' => [ 'class' => LoadMonitorNull::class ]
] );
}
@ -400,7 +400,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
$lb = new LoadBalancer( [
'servers' => $servers,
'localDomain' => new DatabaseDomain( 'my_unittest_wiki', null, 'unittest_' ),
'loadMonitorClass' => LoadMonitorNull::class
'loadMonitor' => [ 'class' => LoadMonitorNull::class ]
] );
$this->assertTrue( $lb->getServerAttributes( 0 )[Database::ATTR_DB_LEVEL_LOCKING] );
@ -429,7 +429,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
$lb = new LoadBalancer( [
'servers' => $servers,
'localDomain' => new DatabaseDomain( 'my_unittest_wiki', null, 'unittest_' ),
'loadMonitorClass' => LoadMonitorNull::class
'loadMonitor' => [ 'class' => LoadMonitorNull::class ]
] );
$this->assertFalse( $lb->getServerAttributes( 1 )[Database::ATTR_DB_LEVEL_LOCKING] );