Merge "Fix "Undefined index: type" warning on LoginSignupSpecialPage"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 10 Jun 2016 01:29:04 +0000 (01:29 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 10 Jun 2016 01:29:04 +0000 (01:29 +0000)
13 files changed:
includes/DefaultSettings.php
includes/MediaWiki.php
includes/ServiceWiring.php
includes/api/ApiStashEdit.php
includes/jobqueue/jobs/RefreshLinksJob.php
includes/site/DBSiteStore.php
includes/site/FileBasedSiteLookup.php
includes/specials/SpecialCreateAccount.php
includes/specials/SpecialUserLogin.php
includes/widget/SearchInputWidget.php [changed mode: 0755->0644]
resources/src/mediawiki.ui/components/inputs.less
tests/phpunit/includes/site/DBSiteStoreTest.php
tests/phpunit/includes/site/FileBasedSiteLookupTest.php

index dc0b60c..80e199a 100644 (file)
@@ -5982,6 +5982,12 @@ $wgTrxProfilerLimits = [
                'writes' => 0,
                'readQueryTime' => 5
        ],
+       // Deferred updates that run after HTTP response is sent
+       'PostSend' => [
+               'readQueryTime' => 5,
+               'writeQueryTime' => 1,
+               'maxAffected' => 500
+       ],
        // Background job runner
        'JobRunner' => [
                'readQueryTime' => 30,
index ee03f02..21857b9 100644 (file)
@@ -764,9 +764,13 @@ class MediaWiki {
                // Assure deferred updates are not in the main transaction
                wfGetLBFactory()->commitMasterChanges( __METHOD__ );
 
-               // Ignore things like master queries/connections on GET requests
-               // as long as they are in deferred updates (which catch errors).
-               Profiler::instance()->getTransactionProfiler()->resetExpectations();
+               // Loosen DB query expectations since the HTTP client is unblocked
+               $trxProfiler = Profiler::instance()->getTransactionProfiler();
+               $trxProfiler->resetExpectations();
+               $trxProfiler->setExpectations(
+                       $this->config->get( 'TrxProfilerLimits' )['PostSend'],
+                       __METHOD__
+               );
 
                // Do any deferred jobs
                DeferredUpdates::doUpdates( 'enqueue' );
index 338f306..b076d07 100644 (file)
@@ -61,9 +61,6 @@ return [
 
        'SiteStore' => function( MediaWikiServices $services ) {
                $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
-               $rawSiteStore->setLanguageCodeMapping(
-                       $services->getMainConfig()->get( 'DummyLanguageCodes' ) ?: []
-               );
 
                // TODO: replace wfGetCache with a CacheFactory service.
                // TODO: replace wfIsHHVM with a capabilities service.
index 51da606..814a111 100644 (file)
@@ -41,6 +41,7 @@ class ApiStashEdit extends ApiBase {
        const ERROR_UNCACHEABLE = 'uncacheable';
 
        const PRESUME_FRESH_TTL_SEC = 30;
+       const MAX_CACHE_TTL = 300; // 5 minutes
 
        public function execute() {
                $user = $this->getUser();
@@ -319,64 +320,10 @@ class ApiStashEdit extends ApiBase {
                        return $editInfo;
                }
 
-               $dbr = wfGetDB( DB_SLAVE );
+               $stats->increment( 'editstash.cache_misses.proven_stale' );
+               $logger->info( "Stale cache for key '$key'; old key with outside edits. (age: $age sec)" );
 
-               $templates = []; // conditions to find changes/creations
-               $templateUses = 0; // expected existing templates
-               foreach ( $editInfo->output->getTemplateIds() as $ns => $stuff ) {
-                       foreach ( $stuff as $dbkey => $revId ) {
-                               $templates[(string)$ns][$dbkey] = (int)$revId;
-                               ++$templateUses;
-                       }
-               }
-               // Check that no templates used in the output changed...
-               if ( count( $templates ) ) {
-                       $res = $dbr->select(
-                               'page',
-                               [ 'ns' => 'page_namespace', 'dbk' => 'page_title', 'page_latest' ],
-                               $dbr->makeWhereFrom2d( $templates, 'page_namespace', 'page_title' ),
-                               __METHOD__
-                       );
-                       $changed = false;
-                       foreach ( $res as $row ) {
-                               $changed = $changed || ( $row->page_latest != $templates[$row->ns][$row->dbk] );
-                       }
-
-                       if ( $changed || $res->numRows() != $templateUses ) {
-                               $stats->increment( 'editstash.cache_misses.proven_stale' );
-                               $logger->info( "Stale cache for key '$key'; template changed. (age: $age sec)" );
-                               return false;
-                       }
-               }
-
-               $files = []; // conditions to find changes/creations
-               foreach ( $editInfo->output->getFileSearchOptions() as $name => $options ) {
-                       $files[$name] = (string)$options['sha1'];
-               }
-               // Check that no files used in the output changed...
-               if ( count( $files ) ) {
-                       $res = $dbr->select(
-                               'image',
-                               [ 'name' => 'img_name', 'img_sha1' ],
-                               [ 'img_name' => array_keys( $files ) ],
-                               __METHOD__
-                       );
-                       $changed = false;
-                       foreach ( $res as $row ) {
-                               $changed = $changed || ( $row->img_sha1 != $files[$row->name] );
-                       }
-
-                       if ( $changed || $res->numRows() != count( $files ) ) {
-                               $stats->increment( 'editstash.cache_misses.proven_stale' );
-                               $logger->info( "Stale cache for key '$key'; file changed. (age: $age sec)" );
-                               return false;
-                       }
-               }
-
-               $stats->increment( 'editstash.cache_hits.proven_fresh' );
-               $logger->debug( "Verified cache hit for key '$key' (age: $age sec)." );
-
-               return $editInfo;
+               return false;
        }
 
        /**
@@ -437,7 +384,7 @@ class ApiStashEdit extends ApiBase {
                // If an item is renewed, mind the cache TTL determined by config and parser functions.
                // Put an upper limit on the TTL for sanity to avoid extreme template/file staleness.
                $since = time() - wfTimestamp( TS_UNIX, $parserOutput->getTimestamp() );
-               $ttl = min( $parserOutput->getCacheExpiry() - $since, 5 * 60 );
+               $ttl = min( $parserOutput->getCacheExpiry() - $since, self::MAX_CACHE_TTL );
 
                if ( $ttl > 0 && !$parserOutput->getFlag( 'vary-revision' ) ) {
                        // Only store what is actually needed
index 9711496..8870569 100644 (file)
@@ -40,13 +40,13 @@ class RefreshLinksJob extends Job {
        const PARSE_THRESHOLD_SEC = 1.0;
        /** @var integer Lag safety margin when comparing root job times to last-refresh times */
        const CLOCK_FUDGE = 10;
+       /** @var integer How many seconds to wait for slaves to catch up */
+       const LAG_WAIT_TIMEOUT = 15;
 
        function __construct( Title $title, array $params ) {
                parent::__construct( 'refreshLinks', $title, $params );
                // Avoid the overhead of de-duplication when it would be pointless
                $this->removeDuplicates = (
-                       // Master positions won't match
-                       !isset( $params['masterPos'] ) &&
                        // Ranges rarely will line up
                        !isset( $params['range'] ) &&
                        // Multiple pages per job make matches unlikely
@@ -83,20 +83,22 @@ class RefreshLinksJob extends Job {
 
                // Job to update all (or a range of) backlink pages for a page
                if ( !empty( $this->params['recursive'] ) ) {
+                       // When the base job branches, wait for the slaves to catch up to the master.
+                       // From then on, we know that any template changes at the time the base job was
+                       // enqueued will be reflected in backlink page parses when the leaf jobs run.
+                       if ( !isset( $params['range'] ) ) {
+                               try {
+                                       wfGetLBFactory()->waitForReplication( [
+                                               'wiki'    => wfWikiID(),
+                                               'timeout' => self::LAG_WAIT_TIMEOUT
+                                       ] );
+                               } catch ( DBReplicationWaitError $e ) { // only try so hard
+                                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                                       $stats->increment( 'refreshlinks.lag_wait_failed' );
+                               }
+                       }
                        // Carry over information for de-duplication
                        $extraParams = $this->getRootJobParams();
-                       // Avoid slave lag when fetching templates.
-                       // When the outermost job is run, we know that the caller that enqueued it must have
-                       // committed the relevant changes to the DB by now. At that point, record the master
-                       // position and pass it along as the job recursively breaks into smaller range jobs.
-                       // Hopefully, when leaf jobs are popped, the slaves will have reached that position.
-                       if ( isset( $this->params['masterPos'] ) ) {
-                               $extraParams['masterPos'] = $this->params['masterPos'];
-                       } elseif ( wfGetLB()->getServerCount() > 1 ) {
-                               $extraParams['masterPos'] = wfGetLB()->getMasterPos();
-                       } else {
-                               $extraParams['masterPos'] = false;
-                       }
                        $extraParams['triggeredRecursive'] = true;
                        // Convert this into no more than $wgUpdateRowsPerJob RefreshLinks per-title
                        // jobs and possibly a recursive RefreshLinks job for the rest of the backlinks
@@ -109,29 +111,18 @@ class RefreshLinksJob extends Job {
                        JobQueueGroup::singleton()->push( $jobs );
                // Job to update link tables for a set of titles
                } elseif ( isset( $this->params['pages'] ) ) {
-                       $this->waitForMasterPosition();
                        foreach ( $this->params['pages'] as $pageId => $nsAndKey ) {
                                list( $ns, $dbKey ) = $nsAndKey;
                                $this->runForTitle( Title::makeTitleSafe( $ns, $dbKey ) );
                        }
                // Job to update link tables for a given title
                } else {
-                       $this->waitForMasterPosition();
                        $this->runForTitle( $this->title );
                }
 
                return true;
        }
 
-       protected function waitForMasterPosition() {
-               if ( !empty( $this->params['masterPos'] ) && wfGetLB()->getServerCount() > 1 ) {
-                       // Wait for the current/next slave DB handle to catch up to the master.
-                       // This way, we get the correct page_latest for templates or files that just
-                       // changed milliseconds ago, having triggered this job to begin with.
-                       wfGetLB()->waitFor( $this->params['masterPos'] );
-               }
-       }
-
        /**
         * @param Title $title
         * @return bool
index c1c10c2..974789f 100644 (file)
@@ -40,11 +40,6 @@ class DBSiteStore implements SiteStore {
         */
        private $dbLoadBalancer;
 
-       /**
-        * @var string[]
-        */
-       private $languageCodeMapping = [];
-
        /**
         * @since 1.27
         *
@@ -101,17 +96,15 @@ class DBSiteStore implements SiteStore {
                );
 
                foreach ( $res as $row ) {
-                       $languageCode = $row->site_language === '' ? null : $row->site_language;
-                       if ( isset( $this->languageCodeMapping[ $languageCode ] ) ) {
-                               $languageCode = $this->languageCodeMapping[ $languageCode ];
-                       }
-
                        $site = Site::newForType( $row->site_type );
                        $site->setGlobalId( $row->site_global_key );
                        $site->setInternalId( (int)$row->site_id );
                        $site->setForward( (bool)$row->site_forward );
                        $site->setGroup( $row->site_group );
-                       $site->setLanguageCode( $languageCode );
+                       $site->setLanguageCode( $row->site_language === ''
+                               ? null
+                               : $row->site_language
+                       );
                        $site->setSource( $row->site_source );
                        $site->setExtraData( unserialize( $row->site_data ) );
                        $site->setExtraConfig( unserialize( $row->site_config ) );
@@ -294,13 +287,4 @@ class DBSiteStore implements SiteStore {
                return $ok;
        }
 
-       /**
-        * Provide an array that maps language codes
-        *
-        * @param string[] $newMapping
-        */
-       public function setLanguageCodeMapping( array $newMapping ) {
-               $this->languageCodeMapping = $newMapping;
-       }
-
 }
index 424d8e6..9654440 100644 (file)
@@ -42,11 +42,6 @@ class FileBasedSiteLookup implements SiteLookup {
         */
        private $cacheFile;
 
-       /**
-        * @var string[]
-        */
-       private $languageCodeMapping = [];
-
        /**
         * @param string $cacheFile
         */
@@ -123,18 +118,13 @@ class FileBasedSiteLookup implements SiteLookup {
         * @return Site
         */
        private function newSiteFromArray( array $data ) {
-               $languageCode = $data['language'];
-               if ( isset( $this->languageCodeMapping[ $languageCode ] ) ) {
-                       $languageCode = $this->languageCodeMapping[ $languageCode ];
-               }
-
                $siteType = array_key_exists( 'type', $data ) ? $data['type'] : Site::TYPE_UNKNOWN;
                $site = Site::newForType( $siteType );
 
                $site->setGlobalId( $data['globalid'] );
                $site->setForward( $data['forward'] );
                $site->setGroup( $data['group'] );
-               $site->setLanguageCode( $languageCode );
+               $site->setLanguageCode( $data['language'] );
                $site->setSource( $data['source'] );
                $site->setExtraData( $data['data'] );
                $site->setExtraConfig( $data['config'] );
@@ -146,13 +136,4 @@ class FileBasedSiteLookup implements SiteLookup {
                return $site;
        }
 
-       /**
-        * Provide an array that maps language codes
-        *
-        * @param string[] $newMapping
-        */
-       public function setLanguageCodeMapping( array $newMapping ) {
-               $this->languageCodeMapping = $newMapping;
-       }
-
 }
index b046bf9..9f3e5f0 100644 (file)
@@ -160,7 +160,7 @@ class SpecialCreateAccount extends LoginSignupSpecialPage {
        }
 
        protected function logAuthResult( $success, $status = null ) {
-               LoggerFactory::getInstance( 'authmanager-stats' )->info( 'Account creation attempt', [
+               LoggerFactory::getInstance( 'authevents' )->info( 'Account creation attempt', [
                        'event' => 'accountcreation',
                        'successful' => $success,
                        'status' => $status,
index 28c68aa..493ae2a 100644 (file)
@@ -154,7 +154,7 @@ class SpecialUserLogin extends LoginSignupSpecialPage {
        }
 
        protected function logAuthResult( $success, $status = null ) {
-               LoggerFactory::getInstance( 'authmanager-stats' )->info( 'Login attempt', [
+               LoggerFactory::getInstance( 'authevents' )->info( 'Login attempt', [
                        'event' => 'login',
                        'successful' => $success,
                        'status' => $status,
old mode 100755 (executable)
new mode 100644 (file)
index 579bd5f..f8d283a 100644 (file)
@@ -108,6 +108,9 @@ input[type="number"],
 .mw-ui-input-inline {
        display: inline-block;
        width: auto;
+       // Make sure we limit `width` to parent element because
+       // in case of text `input` fields, `width: auto;` equals `size` attribute.
+       max-width: 100%;
 }
 
 // mw-ui-input-large
index 316fd89..32dd7f2 100644 (file)
@@ -67,20 +67,6 @@ class DBSiteStoreTest extends MediaWikiTestCase {
                }
        }
 
-       /**
-        * @covers DBSiteStore::getSites
-        * @covers DBSiteStore::setLanguageCodeMapping
-        */
-       public function testLanguageCodeMapping() {
-               TestSites::insertIntoDb();
-
-               $store = $this->newDBSiteStore();
-               $store->setLanguageCodeMapping( [ 'no' => 'nb' ] );
-
-               $site = $store->getSite( 'nowiki' );
-               $this->assertEquals( $site->getLanguageCode(), 'nb' );
-       }
-
        /**
         * @covers DBSiteStore::saveSites
         */
index bebda79..7984795 100644 (file)
@@ -98,15 +98,4 @@ class FileBasedSiteLookupTest extends PHPUnit_Framework_TestCase {
                return tempnam( sys_get_temp_dir(), 'mw-test-sitelist' );
        }
 
-       public function testLanguageCodeMapping() {
-               $sites = $this->getSites();
-               $cacheBuilder = $this->newSitesCacheFileBuilder( $sites );
-               $cacheBuilder->build();
-
-               $cache = new FileBasedSiteLookup( $this->cacheFile );
-               $cache->setLanguageCodeMapping( [ 'en' => 'fa' ] );
-
-               $this->assertEquals( $cache->getSite( 'enwiktionary' )->getLanguageCode(), 'fa' );
-       }
-
 }