From 5d4b009cfd9e98af358e497fadc86b05d42d763b Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Sat, 17 Sep 2016 18:50:56 -0700 Subject: [PATCH] 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 --- includes/ServiceWiring.php | 54 ++---------- includes/db/loadbalancer/LBFactoryMW.php | 106 +++++++++++++++-------- 2 files changed, 73 insertions(+), 87 deletions(-) diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 7cd62ce918..8c7d802d68 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -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 ) { diff --git a/includes/db/loadbalancer/LBFactoryMW.php b/includes/db/loadbalancer/LBFactoryMW.php index f4d17773a3..e943a8ab40 100644 --- a/includes/db/loadbalancer/LBFactoryMW.php +++ b/includes/db/loadbalancer/LBFactoryMW.php @@ -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(), ]; + + 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' ); + } + } + // 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; + $lbConf['srvCache'] = $sCache; } $cCache = ObjectCache::getLocalClusterInstance(); if ( $cCache->getQoS( $cCache::ATTR_EMULATION ) > $cCache::QOS_EMULATION_SQL ) { - $defaults['memCache'] = $cCache; + $lbConf['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; - } + $lbConf['wanCache'] = $wCache; } - return $conf + $defaults; + return $lbConf; } /** -- 2.20.1