From fc1d4d79602415d1362de9286b0729bd86d03fc1 Mon Sep 17 00:00:00 2001 From: daniel Date: Fri, 13 May 2016 21:27:06 +0200 Subject: [PATCH] Fix installer issues introduces by MediaWikiServices This fixes three issues with the installer: 1) Make sure LocalizationCache can find the installer's i18n files. 2) Make sure we don't try to use an SqlBagOStuff for caching before we have a functioning database. 3) Don't try to output HTML when redirecting (this is unrelated to MediaWikiServices, but came up during testing) Bug: T135169 Change-Id: I7caa932024cd771d6fa226a3ac6001c3148ecc9c --- autoload.php | 1 + includes/MediaWikiServices.php | 3 ++ includes/cache/CacheDependency.php | 29 +++++++++++++++++++ .../cache/localisation/LocalisationCache.php | 13 ++++++--- includes/installer/Installer.php | 16 ++++++++-- includes/installer/WebInstallerOutput.php | 5 +++- includes/objectcache/ObjectCache.php | 14 ++++++++- 7 files changed, 73 insertions(+), 8 deletions(-) diff --git a/autoload.php b/autoload.php index f79bace67f..cf0e4171d0 100644 --- a/autoload.php +++ b/autoload.php @@ -772,6 +772,7 @@ $wgAutoloadLocalClasses = [ 'MagicWord' => __DIR__ . '/includes/MagicWord.php', 'MagicWordArray' => __DIR__ . '/includes/MagicWordArray.php', 'MailAddress' => __DIR__ . '/includes/mail/MailAddress.php', + 'MainConfigDependency' => __DIR__ . '/includes/cache/CacheDependency.php', 'Maintenance' => __DIR__ . '/maintenance/Maintenance.php', 'MaintenanceFormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php', 'MakeTestEdits' => __DIR__ . '/maintenance/makeTestEdits.php', diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php index 891f426d74..71e58afdb7 100644 --- a/includes/MediaWikiServices.php +++ b/includes/MediaWikiServices.php @@ -13,6 +13,7 @@ use Liuggio\StatsdClient\Factory\StatsdDataFactory; use LoadBalancer; use MediaWiki\Services\ServiceContainer; use MWException; +use ObjectCache; use ResourceLoader; use SearchEngine; use SearchEngineConfig; @@ -222,6 +223,8 @@ class MediaWikiServices extends ServiceContainer { foreach ( $destroy as $name ) { $services->disableService( $name ); } + + ObjectCache::clear(); } /** diff --git a/includes/cache/CacheDependency.php b/includes/cache/CacheDependency.php index 2d29d86513..a59ba97d0a 100644 --- a/includes/cache/CacheDependency.php +++ b/includes/cache/CacheDependency.php @@ -20,6 +20,7 @@ * @file * @ingroup Cache */ +use MediaWiki\MediaWikiServices; /** * This class stores an arbitrary value along with its dependencies. @@ -244,6 +245,34 @@ class GlobalDependency extends CacheDependency { } } +/** + * @ingroup Cache + */ +class MainConfigDependency extends CacheDependency { + private $name; + private $value; + + function __construct( $name ) { + $this->name = $name; + $this->value = $this->getConfig()->get( $this->name ); + } + + private function getConfig() { + return MediaWikiServices::getInstance()->getMainConfig(); + } + + /** + * @return bool + */ + function isExpired() { + if ( !$this->getConfig()->has( $this->name ) ) { + return true; + } + + return $this->getConfig()->get( $this->name ) != $this->value; + } +} + /** * @ingroup Cache */ diff --git a/includes/cache/localisation/LocalisationCache.php b/includes/cache/localisation/LocalisationCache.php index dd7d81a33c..0fb9ed8561 100644 --- a/includes/cache/localisation/LocalisationCache.php +++ b/includes/cache/localisation/LocalisationCache.php @@ -23,6 +23,7 @@ use Cdb\Reader as CdbReader; use Cdb\Writer as CdbWriter; use CLDRPluralRuleParser\Evaluator; +use MediaWiki\MediaWikiServices; /** * Class for caching the contents of localisation files, Messages*.php @@ -802,12 +803,15 @@ class LocalisationCache { * @return array */ public function getMessagesDirs() { - global $wgMessagesDirs, $IP; + global $IP; + + $config = MediaWikiServices::getInstance()->getMainConfig(); + $messagesDirs = $config->get( 'MessagesDirs' ); return [ 'core' => "$IP/languages/i18n", 'api' => "$IP/includes/api/i18n", 'oojs-ui' => "$IP/resources/lib/oojs-ui/i18n", - ] + $wgMessagesDirs; + ] + $messagesDirs; } /** @@ -958,8 +962,9 @@ class LocalisationCache { # Add cache dependencies for any referenced globals $deps['wgExtensionMessagesFiles'] = new GlobalDependency( 'wgExtensionMessagesFiles' ); - // $wgMessagesDirs is used in LocalisationCache::getMessagesDirs() - $deps['wgMessagesDirs'] = new GlobalDependency( 'wgMessagesDirs' ); + // The 'MessagesDirs' config setting is used in LocalisationCache::getMessagesDirs(). + // We use the key 'wgMessagesDirs' for historical reasons. + $deps['wgMessagesDirs'] = new MainConfigDependency( 'MessagesDirs' ); $deps['version'] = new ConstantDependency( 'LocalisationCache::VERSION' ); # Add dependencies to the cache entry diff --git a/includes/installer/Installer.php b/includes/installer/Installer.php index a9f219f9bc..85b1013049 100644 --- a/includes/installer/Installer.php +++ b/includes/installer/Installer.php @@ -20,6 +20,7 @@ * @file * @ingroup Deployment */ +use MediaWiki\MediaWikiServices; /** * This documentation group collects source code files with deployment functionality. @@ -383,14 +384,24 @@ abstract class Installer { $configOverrides->set( 'MessagesDirs', $messageDirs ); - return new MultiConfig( [ $configOverrides, $baseConfig ] ); + $installerConfig = new MultiConfig( [ $configOverrides, $baseConfig ] ); + + // make sure we use the installer config as the main config + $configRegistry = $baseConfig->get( 'ConfigRegistry' ); + $configRegistry['main'] = function() use ( $installerConfig ) { + return $installerConfig; + }; + + $configOverrides->set( 'ConfigRegistry', $configRegistry ); + + return $installerConfig; } /** * Constructor, always call this from child classes. */ public function __construct() { - global $wgMemc, $wgUser; + global $wgMemc, $wgUser, $wgObjectCaches; $defaultConfig = new GlobalVarConfig(); // all the stuff from DefaultSettings.php $installerConfig = self::getInstallerConfig( $defaultConfig ); @@ -411,6 +422,7 @@ abstract class Installer { // Disable object cache (otherwise CACHE_ANYTHING will try CACHE_DB and // SqlBagOStuff will then throw since we just disabled wfGetDB) + $wgObjectCaches = MediaWikiServices::getInstance()->getMainConfig()->get( 'ObjectCaches' ); $wgMemc = ObjectCache::getInstance( CACHE_NONE ); // Having a user with id = 0 safeguards us from DB access via User::loadOptions(). diff --git a/includes/installer/WebInstallerOutput.php b/includes/installer/WebInstallerOutput.php index b4c8aa8649..f8dc8ee57f 100644 --- a/includes/installer/WebInstallerOutput.php +++ b/includes/installer/WebInstallerOutput.php @@ -115,7 +115,10 @@ class WebInstallerOutput { public function output() { $this->flush(); - $this->outputFooter(); + + if ( !$this->redirectTarget ) { + $this->outputFooter(); + } } /** diff --git a/includes/objectcache/ObjectCache.php b/includes/objectcache/ObjectCache.php index 24846e6ed6..e1bb2db7c5 100644 --- a/includes/objectcache/ObjectCache.php +++ b/includes/objectcache/ObjectCache.php @@ -23,6 +23,7 @@ use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; +use MediaWiki\Services\ServiceDisabledException; /** * Functions to get cache objects @@ -226,7 +227,18 @@ class ObjectCache { return self::getInstance( $candidate ); } } - return self::getInstance( CACHE_DB ); + + try { + // Make sure we actually have a DB backend before falling back to CACHE_DB + MediaWikiServices::getInstance()->getDBLoadBalancer(); + $candidate = CACHE_DB; + } catch ( ServiceDisabledException $e ) { + // The LoadBalancer is disabled, probably because + // MediaWikiServices::disableStorageBackend was called. + $candidate = CACHE_NONE; + } + + return self::getInstance( $candidate ); } /** -- 2.20.1