Cleanup ServiceWiring/LBFactoryMW interaction
authorAaron Schulz <aschulz@wikimedia.org>
Sun, 18 Sep 2016 01:50:56 +0000 (18:50 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Mon, 19 Sep 2016 16:19:06 +0000 (09:19 -0700)
* 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
includes/db/loadbalancer/LBFactoryMW.php

index 7cd62ce..8c7d802 100644 (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 ) {
index f4d1777..e943a8a 100644 (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(),
                ];
+
+               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;
        }
 
        /**