Cleanup ServiceWiring/LBFactoryMW interaction

* Move almost all the code to LBFactoryMW and inject the main config.
* Make LBFactoryMW no longer extend anything, which is now pointless.
* Let site admins explicitly set "servers" and "externalServers" arrays.
* Pass in the $wgDBschema field regardless of $wgDBtype. It defaults to
  null, so no one would bother setting it if they did not want to use it.

Change-Id: I51f15c0f5d98a73907c51958bdb82dea76b3e38c
This commit is contained in:
Aaron Schulz 2016-09-17 18:50:56 -07:00
parent 2a00a6e256
commit 5d4b009cfd
2 changed files with 80 additions and 94 deletions

View file

@ -45,57 +45,13 @@ return [
'DBLoadBalancerFactory' => function( MediaWikiServices $services ) {
$mainConfig = $services->getMainConfig();
$lbConf = $mainConfig->get( 'LBFactoryConf' );
$lbConf += [
'localDomain' => new DatabaseDomain(
$mainConfig->get( 'DBname' ), null, $mainConfig->get( 'DBprefix' ) ),
// TODO: replace the global wfConfiguredReadOnlyReason() with a service.
'readOnlyReason' => wfConfiguredReadOnlyReason(),
];
$lbConf = LBFactoryMW::applyDefaultConfig(
$mainConfig->get( 'LBFactoryConf' ),
$mainConfig
);
$class = LBFactoryMW::getLBFactoryClass( $lbConf );
if ( $class === 'LBFactorySimple' ) {
if ( is_array( $mainConfig->get( 'DBservers' ) ) ) {
foreach ( $mainConfig->get( 'DBservers' ) as $i => $server ) {
if ( $server['type'] === 'sqlite' ) {
$server += [ 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ) ];
}
$lbConf['servers'][$i] = $server + [
'schema' => $mainConfig->get( 'DBmwschema' ),
'tablePrefix' => $mainConfig->get( 'DBprefix' ),
'flags' => DBO_DEFAULT,
'sqlMode' => $mainConfig->get( 'SQLMode' ),
'utf8Mode' => $mainConfig->get( 'DBmysql5' )
];
}
} else {
$flags = DBO_DEFAULT;
$flags |= $mainConfig->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
$flags |= $mainConfig->get( 'DBssl' ) ? DBO_SSL : 0;
$flags |= $mainConfig->get( 'DBcompress' ) ? DBO_COMPRESS : 0;
$server = [
'host' => $mainConfig->get( 'DBserver' ),
'user' => $mainConfig->get( 'DBuser' ),
'password' => $mainConfig->get( 'DBpassword' ),
'dbname' => $mainConfig->get( 'DBname' ),
'schema' => $mainConfig->get( 'DBmwschema' ),
'tablePrefix' => $mainConfig->get( 'DBprefix' ),
'type' => $mainConfig->get( 'DBtype' ),
'load' => 1,
'flags' => $flags,
'sqlMode' => $mainConfig->get( 'SQLMode' ),
'utf8Mode' => $mainConfig->get( 'DBmysql5' )
];
if ( $server['type'] === 'sqlite' ) {
$server[ 'dbDirectory'] = $mainConfig->get( 'SQLiteDataDir' );
}
$lbConf['servers'] = [ $server ];
}
$lbConf['externalServers'] = $mainConfig->get( 'ExternalServers' );
}
return new $class( LBFactoryMW::applyDefaultConfig( $lbConf ) );
return new $class( $lbConf );
},
'DBLoadBalancer' => function( MediaWikiServices $services ) {

View file

@ -27,28 +27,21 @@ use MediaWiki\Logger\LoggerFactory;
* Legacy MediaWiki-specific class for generating database load balancers
* @ingroup Database
*/
abstract class LBFactoryMW extends LBFactory {
abstract class LBFactoryMW {
/**
* Construct a factory based on a configuration array (typically from $wgLBFactoryConf)
* @param array $conf
* @TODO: inject objects via dependency framework
*/
public function __construct( array $conf ) {
parent::__construct( self::applyDefaultConfig( $conf ) );
}
/**
* @param array $conf
* @param array $lbConf Config for LBFactory::__construct()
* @param Config $mainConfig Main config object from MediaWikiServices
* @return array
* @TODO: inject objects via dependency framework
*/
public static function applyDefaultConfig( array $conf ) {
global $wgDBtype, $wgSQLMode, $wgDBmysql5, $wgDBname, $wgDBprefix, $wgDBmwschema;
public static function applyDefaultConfig( array $lbConf, Config $mainConfig ) {
global $wgCommandLineMode;
$defaults = [
'localDomain' => new DatabaseDomain( $wgDBname, null, $wgDBprefix ),
'hostname' => wfHostname(),
$lbConf += [
'localDomain' => new DatabaseDomain(
$mainConfig->get( 'DBname' ),
null,
$mainConfig->get( 'DBprefix' )
),
'profiler' => Profiler::instance(),
'trxProfiler' => Profiler::instance()->getTransactionProfiler(),
'replLogger' => LoggerFactory::getInstance( 'DBReplication' ),
@ -57,39 +50,76 @@ abstract class LBFactoryMW extends LBFactory {
'perfLogger' => LoggerFactory::getInstance( 'DBPerformance' ),
'errorLogger' => [ MWExceptionHandler::class, 'logException' ],
'cliMode' => $wgCommandLineMode,
'agent' => ''
'hostname' => wfHostname(),
// TODO: replace the global wfConfiguredReadOnlyReason() with a service.
'readOnlyReason' => wfConfiguredReadOnlyReason(),
];
// Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804)
$sCache = ObjectCache::getLocalServerInstance();
if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) {
$defaults['srvCache'] = $sCache;
}
$cCache = ObjectCache::getLocalClusterInstance();
if ( $cCache->getQoS( $cCache::ATTR_EMULATION ) > $cCache::QOS_EMULATION_SQL ) {
$defaults['memCache'] = $cCache;
}
$wCache = ObjectCache::getMainWANInstance();
if ( $wCache->getQoS( $wCache::ATTR_EMULATION ) > $wCache::QOS_EMULATION_SQL ) {
$defaults['wanCache'] = $wCache;
}
// Determine schema defaults. Currently Microsoft SQL Server uses $wgDBmwschema,
// and everything else doesn't use a schema (e.g. null)
// Although postgres and oracle support schemas, we don't use them (yet)
// to maintain backwards compatibility
$schema = ( $wgDBtype === 'mssql' ) ? $wgDBmwschema : null;
if ( isset( $conf['serverTemplate'] ) ) { // LBFactoryMulti
$conf['serverTemplate']['schema'] = $schema;
$conf['serverTemplate']['sqlMode'] = $wgSQLMode;
$conf['serverTemplate']['utf8Mode'] = $wgDBmysql5;
} elseif ( isset( $conf['servers'] ) ) { // LBFactorySimple
foreach ( $conf['servers'] as $i => $server ) {
$conf['servers'][$i]['schema'] = $schema;
if ( $lbConf['class'] === 'LBFactorySimple' ) {
if ( isset( $lbConf['servers'] ) ) {
// Server array is already explicitly configured; leave alone
} elseif ( is_array( $mainConfig->get( 'DBservers' ) ) ) {
foreach ( $mainConfig->get( 'DBservers' ) as $i => $server ) {
if ( $server['type'] === 'sqlite' ) {
$server += [ 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ) ];
}
$lbConf['servers'][$i] = $server + [
'schema' => $mainConfig->get( 'DBmwschema' ),
'tablePrefix' => $mainConfig->get( 'DBprefix' ),
'flags' => DBO_DEFAULT,
'sqlMode' => $mainConfig->get( 'SQLMode' ),
'utf8Mode' => $mainConfig->get( 'DBmysql5' )
];
}
} else {
$flags = DBO_DEFAULT;
$flags |= $mainConfig->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
$flags |= $mainConfig->get( 'DBssl' ) ? DBO_SSL : 0;
$flags |= $mainConfig->get( 'DBcompress' ) ? DBO_COMPRESS : 0;
$server = [
'host' => $mainConfig->get( 'DBserver' ),
'user' => $mainConfig->get( 'DBuser' ),
'password' => $mainConfig->get( 'DBpassword' ),
'dbname' => $mainConfig->get( 'DBname' ),
'schema' => $mainConfig->get( 'DBmwschema' ),
'tablePrefix' => $mainConfig->get( 'DBprefix' ),
'type' => $mainConfig->get( 'DBtype' ),
'load' => 1,
'flags' => $flags,
'sqlMode' => $mainConfig->get( 'SQLMode' ),
'utf8Mode' => $mainConfig->get( 'DBmysql5' )
];
if ( $server['type'] === 'sqlite' ) {
$server[ 'dbDirectory'] = $mainConfig->get( 'SQLiteDataDir' );
}
$lbConf['servers'] = [ $server ];
}
if ( !isset( $lbConf['externalServers'] ) ) {
$lbConf['externalServers'] = $mainConfig->get( 'ExternalServers' );
}
} elseif ( $lbConf['class'] === 'LBFactoryMulti' ) {
if ( isset( $lbConf['serverTemplate'] ) ) {
$lbConf['serverTemplate']['schema'] = $mainConfig->get( 'DBmwschema' );
$lbConf['serverTemplate']['sqlMode'] = $mainConfig->get( 'SQLMode' );
$lbConf['serverTemplate']['utf8Mode'] = $mainConfig->get( 'DBmysql5' );
}
}
return $conf + $defaults;
// Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804)
$sCache = ObjectCache::getLocalServerInstance();
if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) {
$lbConf['srvCache'] = $sCache;
}
$cCache = ObjectCache::getLocalClusterInstance();
if ( $cCache->getQoS( $cCache::ATTR_EMULATION ) > $cCache::QOS_EMULATION_SQL ) {
$lbConf['memCache'] = $cCache;
}
$wCache = ObjectCache::getMainWANInstance();
if ( $wCache->getQoS( $wCache::ATTR_EMULATION ) > $wCache::QOS_EMULATION_SQL ) {
$lbConf['wanCache'] = $wCache;
}
return $lbConf;
}
/**