Merge "Made ReplicatedBagOStuff wrapping the SQL class the default stash"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 24 Jun 2015 20:09:53 +0000 (20:09 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 24 Jun 2015 20:09:53 +0000 (20:09 +0000)
1  2 
includes/DefaultSettings.php
includes/objectcache/SqlBagOStuff.php

@@@ -82,14 -82,6 +82,14 @@@ $wgVersion = '1.26alpha'
   */
  $wgSitename = 'MediaWiki';
  
 +/**
 + * When the wiki is running behind a proxy and this is set to true, assumes that the proxy exposes
 + * the wiki on the standard ports (443 for https and 80 for http).
 + * @var bool
 + * @since 1.26
 + */
 +$wgAssumeProxiesUseDefaultProtocolPorts = true;
 +
  /**
   * URL of the server.
   *
@@@ -480,13 -472,13 +480,13 @@@ $wgImgAuthUrlPathMap = array()
   *
   * These settings describe a foreign MediaWiki installation. They are optional, and will be ignored
   * for local repositories:
 - *   - descBaseUrl       URL of image description pages, e.g. http://en.wikipedia.org/wiki/File:
 + *   - descBaseUrl       URL of image description pages, e.g. https://en.wikipedia.org/wiki/File:
   *   - scriptDirUrl      URL of the MediaWiki installation, equivalent to $wgScriptPath, e.g.
 - *                       http://en.wikipedia.org/w
 + *                       https://en.wikipedia.org/w
   *   - scriptExtension   Script extension of the MediaWiki installation, equivalent to
   *                       $wgScriptExtension, e.g. .php5 defaults to .php
   *
 - *   - articleUrl        Equivalent to $wgArticlePath, e.g. http://en.wikipedia.org/wiki/$1
 + *   - articleUrl        Equivalent to $wgArticlePath, e.g. https://en.wikipedia.org/wiki/$1
   *   - fetchDescription  Fetch the text of the remote file description page. Equivalent to
   *                       $wgFetchCommonsDescriptions.
   *   - abbrvThreshold    File names over this size will use the short form of thumbnail names.
@@@ -717,7 -709,7 +717,7 @@@ $wgMaxUploadSize = 1024 * 1024 * 100; 
   *
   * @par Example:
   * @code
 - * $wgUploadNavigationUrl = 'http://commons.wikimedia.org/wiki/Special:Upload';
 + * $wgUploadNavigationUrl = 'https://commons.wikimedia.org/wiki/Special:Upload';
   * @endcode
   */
  $wgUploadNavigationUrl = false;
@@@ -777,7 -769,7 +777,7 @@@ $wgHashedSharedUploadDirectory = true
   *
   * Please specify the namespace, as in the example below.
   */
 -$wgRepositoryBaseUrl = "http://commons.wikimedia.org/wiki/File:";
 +$wgRepositoryBaseUrl = "https://commons.wikimedia.org/wiki/File:";
  
  /**
   * This is the list of preferred extensions for uploading files. Uploading files
@@@ -978,14 -970,6 +978,14 @@@ $wgJpegTran = '/usr/bin/jpegtran'
   */
  $wgExiv2Command = '/usr/bin/exiv2';
  
 +
 +/**
 + * Path to exiftool binary. Used for lossless ICC profile swapping.
 + *
 + * @since 1.26
 + */
 +$wgExiftool = '/usr/bin/exiftool';
 +
  /**
   * Scalable Vector Graphics (SVG) may be uploaded as images.
   * Since SVG support is not yet standard in browsers, it is
@@@ -1338,14 -1322,6 +1338,14 @@@ $wgUploadThumbnailRenderHttpCustomHost 
   */
  $wgUploadThumbnailRenderHttpCustomDomain = false;
  
 +/**
 + * When this variable is true and JPGs use the sRGB ICC profile, swaps it for the more lightweight
 + * (and free) TinyRGB profile when generating thumbnails.
 + *
 + * @since 1.26
 + */
 +$wgUseTinyRGBForJPGThumbnails = false;
 +
  /**
   * Default parameters for the "<gallery>" tag
   */
@@@ -2175,6 -2151,19 +2175,19 @@@ $wgObjectCaches = array
        CACHE_ACCEL => array( 'factory' => 'ObjectCache::newAccelerator' ),
        CACHE_MEMCACHED => array( 'factory' => 'ObjectCache::newMemcached', 'loggroup' => 'memcached' ),
  
+       'db-replicated' => array(
+               'class'       => 'ReplicatedBagOStuff',
+               'readFactory' => array(
+                       'class' => 'SqlBagOStuff',
+                       'args'  => array( array( 'slaveOnly' => true ) )
+               ),
+               'writeFactory' => array(
+                       'class' => 'SqlBagOStuff',
+                       'args'  => array( array( 'slaveOnly' => false ) )
+               ),
+               'loggroup'  => 'SQLBagOStuff'
+       ),
        'apc' => array( 'class' => 'APCBagOStuff' ),
        'xcache' => array( 'class' => 'XCacheBagOStuff' ),
        'wincache' => array( 'class' => 'WinCacheBagOStuff' ),
@@@ -2237,6 -2226,7 +2250,7 @@@ $wgWANObjectCaches = array
   * lightweight data like hit counters and user activity. Sites with multiple
   * data-centers should have this use a store that replicates all writes. The
   * store should have enough consistency for CAS operations to be usable.
+  * Reads outside of those needed for merge() may be eventually consistent.
   *
   * The options are:
   *   - db:      Store cache objects in the DB
   *
   * @since 1.26
   */
- $wgMainStash = 'db';
+ $wgMainStash = 'db-replicated';
  
  /**
   * The expiry time for the parser cache, in seconds.
@@@ -2321,13 -2311,11 +2335,13 @@@ $wgAdaptiveMessageCache = false
   * Localisation cache configuration. Associative array with keys:
   * class:       The class to use. May be overridden by extensions.
   *
 - * store:       The location to store cache data. May be 'files', 'db' or
 + * store:       The location to store cache data. May be 'files', 'array', 'db' or
   *              'detect'. If set to "files", data will be in CDB files. If set
   *              to "db", data will be stored to the database. If set to
   *              "detect", files will be used if $wgCacheDirectory is set,
   *              otherwise the database will be used.
 + *              "array" is an experimental option that uses PHP files that
 + *              store static arrays.
   *
   * storeClass:  The class name for the underlying storage. If set to a class
   *              name, it overrides the "store" setting.
@@@ -2395,8 -2383,13 +2409,8 @@@ $wgUseFileCache = false
  $wgFileCacheDepth = 2;
  
  /**
 - * Keep parsed pages in a cache (objectcache table or memcached)
 - * to speed up output of the same page viewed by another user with the
 - * same options.
 - *
 - * This can provide a significant speedup for medium to large pages,
 - * so you probably want to keep it on. Extensions that conflict with the
 - * parser cache should disable the cache on a per-page basis instead.
 + * Kept for extension compatibility; see $wgParserCacheType
 + * @deprecated 1.26
   */
  $wgEnableParserCache = true;
  
@@@ -2821,14 -2814,14 +2835,14 @@@ $wgBrowserBlackList = array
         * - Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC)
         * - [...]
         *
 -       * @link http://en.wikipedia.org/w/index.php?diff=12356041&oldid=12355864
 -       * @link http://en.wikipedia.org/wiki/Template%3AOS9
 +       * @link https://en.wikipedia.org/w/index.php?diff=12356041&oldid=12355864
 +       * @link https://en.wikipedia.org/wiki/Template%3AOS9
         */
        '/^Mozilla\/4\.0 \(compatible; MSIE \d+\.\d+; Mac_PowerPC\)/',
  
        /**
         * Google wireless transcoder, seems to eat a lot of chars alive
 -       * http://it.wikipedia.org/w/index.php?title=Luciano_Ligabue&diff=prev&oldid=8857361
 +       * https://it.wikipedia.org/w/index.php?title=Luciano_Ligabue&diff=prev&oldid=8857361
         */
        '/^Mozilla\/4\.0 \(compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;\)/'
  );
@@@ -4276,59 -4269,6 +4290,59 @@@ $wgActiveUserDays = 30
   * @{
   */
  
 +/**
 + * Password policy for local wiki users. A user's effective policy
 + * is the superset of all policy statements from the policies for the
 + * groups where the user is a member. If more than one group policy
 + * include the same policy statement, the value is the max() of the
 + * values. Note true > false. The 'default' policy group is required,
 + * and serves as the minimum policy for all users. New statements can
 + * be added by appending to $wgPasswordPolicy['checks'].
 + * Statements:
 + *    - MinimalPasswordLength - minimum length a user can set
 + *    - MinimumPasswordLengthToLogin - passwords shorter than this will
 + *            not be allowed to login, regardless if it is correct.
 + *    - MaximalPasswordLength - maximum length password a user is allowed
 + *            to attempt. Prevents DoS attacks with pbkdf2.
 + *    - PasswordCannotMatchUsername - Password cannot match username to
 + *    - PasswordCannotMatchBlacklist - Username/password combination cannot
 + *            match a specific, hardcoded blacklist.
 + * @since 1.26
 + */
 +$wgPasswordPolicy = array(
 +      'policies' => array(
 +              'bureaucrat' => array(
 +                      'MinimalPasswordLength' => 8,
 +                      'MinimumPasswordLengthToLogin' => 1,
 +                      'PasswordCannotMatchUsername' => true,
 +              ),
 +              'sysop' => array(
 +                      'MinimalPasswordLength' => 8,
 +                      'MinimumPasswordLengthToLogin' => 1,
 +                      'PasswordCannotMatchUsername' => true,
 +              ),
 +              'bot' => array(
 +                      'MinimalPasswordLength' => 8,
 +                      'MinimumPasswordLengthToLogin' => 1,
 +                      'PasswordCannotMatchUsername' => true,
 +              ),
 +              'default' => array(
 +                      'MinimalPasswordLength' => 1,
 +                      'PasswordCannotMatchUsername' => true,
 +                      'PasswordCannotMatchBlacklist' => true,
 +                      'MaximalPasswordLength' => 4096,
 +              ),
 +      ),
 +      'checks' => array(
 +              'MinimalPasswordLength' => 'PasswordPolicyChecks::checkMinimalPasswordLength',
 +              'MinimumPasswordLengthToLogin' => 'PasswordPolicyChecks::checkMinimumPasswordLengthToLogin',
 +              'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername',
 +              'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist',
 +              'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength',
 +      ),
 +);
 +
 +
  /**
   * For compatibility with old installations set to false
   * @deprecated since 1.24 will be removed in future
@@@ -4338,9 -4278,8 +4352,9 @@@ $wgPasswordSalt = true
  /**
   * Specifies the minimal length of a user password. If set to 0, empty pass-
   * words are allowed.
 + * @deprecated since 1.26, use $wgPasswordPolicy's MinimalPasswordLength.
   */
 -$wgMinimalPasswordLength = 1;
 +$wgMinimalPasswordLength = false;
  
  /**
   * Specifies the maximal length of a user password (T64685).
   *
   * @warning Unlike other password settings, user with passwords greater than
   *      the maximum will not be able to log in.
 + * @deprecated since 1.26, use $wgPasswordPolicy's MaximalPasswordLength.
   */
 -$wgMaximalPasswordLength = 4096;
 +$wgMaximalPasswordLength = false;
  
  /**
   * Specifies if users should be sent to a password-reset form on login, if their
@@@ -4548,7 -4486,7 +4562,7 @@@ $wgUserrightsInterwikiDelimiter = '@'
  /**
   * This is to let user authenticate using https when they come from http.
   * Based on an idea by George Herbert on wikitech-l:
 - * http://lists.wikimedia.org/pipermail/wikitech-l/2010-October/050039.html
 + * https://lists.wikimedia.org/pipermail/wikitech-l/2010-October/050039.html
   * @since 1.17
   */
  $wgSecureLogin = false;
@@@ -5075,7 -5013,7 +5089,7 @@@ $wgAccountCreationThrottle = 0
   * There's no administrator override on-wiki, so be careful what you set. :)
   * May be an array of regexes or a single string for backwards compatibility.
   *
 - * @see http://en.wikipedia.org/wiki/Regular_expression
 + * @see https://en.wikipedia.org/wiki/Regular_expression
   *
   * @note Each regex needs a beginning/end delimiter, eg: # or /
   */
@@@ -5273,22 -5211,6 +5287,22 @@@ $wgProxyList = array()
   */
  $wgCookieExpiration = 180 * 86400;
  
 +/**
 + * The identifiers of the login cookies that can have their lifetimes
 + * extended independently of all other login cookies.
 + *
 + * @var string[]
 + */
 +$wgExtendedLoginCookies = array( 'UserID', 'Token' );
 +
 +/**
 + * Default login cookie lifetime, in seconds. Setting
 + * $wgExtendLoginCookieExpiration to null will use $wgCookieExpiration to
 + * calculate the cookie lifetime. As with $wgCookieExpiration, 0 will make
 + * login cookies session-only.
 + */
 +$wgExtendedLoginCookieExpiration = null;
 +
  /**
   * Set to set an explicit domain on the login cookies eg, "justthis.domain.org"
   * or ".any.subdomain.net"
@@@ -5622,7 -5544,7 +5636,7 @@@ $wgProfilePerHost = null
   *
   * The host should be running a daemon which can be obtained from MediaWiki
   * Git at:
 - * http://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile
 + * https://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile
   *
   * @deprecated set $wgProfiler['udphost'] instead
   */
@@@ -30,6 -30,7 +30,7 @@@ class SqlBagOStuff extends BagOStuff 
        /** @var LoadBalancer */
        protected $lb;
  
+       /** @var array */
        protected $serverInfos;
  
        /** @var array */
@@@ -53,6 -54,9 +54,9 @@@
        /** @var string */
        protected $tableName = 'objectcache';
  
+       /** @var bool */
+       protected $slaveOnly = false;
        /** @var array UNIX timestamps */
        protected $connFailureTimes = array();
  
         *                  required to hold the largest shard index. Data will be
         *                  distributed across all tables by key hash. This is for
         *                  MySQL bugs 61735 and 61736.
+        *   - slaveOnly:   Whether to only use slave DBs and avoid triggering
+        *                  garbage collection logic of expired items. This only
+        *                  makes sense if the primary DB is used and only if get()
+        *                  calls will be used. This is used by ReplicatedBagOStuff.
         *
         * @param array $params
         */
                if ( isset( $params['shards'] ) ) {
                        $this->shards = intval( $params['shards'] );
                }
+               $this->slaveOnly = !empty( $params['slaveOnly'] );
        }
  
        /**
                                 * However, SQLite has an opposite behavior. And PostgreSQL needs to know
                                 * if we are in transaction or no
                                 */
-                               if ( wfGetDB( DB_MASTER )->getType() == 'mysql' ) {
+                               $index = $this->slaveOnly ? DB_SLAVE : DB_MASTER;
+                               if ( wfGetDB( $index )->getType() == 'mysql' ) {
                                        $this->lb = wfGetLBFactory()->newMainLB();
-                                       $db = $this->lb->getConnection( DB_MASTER );
+                                       $db = $this->lb->getConnection( $index );
                                        $db->clearFlag( DBO_TRX ); // auto-commit mode
                                } else {
-                                       $db = wfGetDB( DB_MASTER );
+                                       $db = wfGetDB( $index );
                                }
                        }
                        if ( $wgDebugDBTransactions ) {
                                try {
                                        $db = $this->getDB( $row->serverIndex );
                                        if ( $this->isExpired( $db, $row->exptime ) ) { // MISS
-                                               $this->debug( "get: key has expired, deleting" );
-                                               # Put the expiry time in the WHERE condition to avoid deleting a
-                                               # newly-inserted value
-                                               $db->delete( $row->tableName,
-                                                       array( 'keyname' => $key, 'exptime' => $row->exptime ),
-                                                       __METHOD__ );
+                                               $this->debug( "get: key has expired" );
                                        } else { // HIT
                                                $values[$key] = $this->unserialize( $db->decodeBlob( $row->value ) );
                                        }
                return $result;
        }
  
 -
 -
        /**
         * @param string $key
         * @param mixed $value
        }
  
        protected function garbageCollect() {
-               if ( !$this->purgePeriod ) {
+               if ( !$this->purgePeriod || $this->slaveOnly ) {
                        // Disabled
                        return;
                }
         */
        protected function unserialize( $serial ) {
                if ( function_exists( 'gzinflate' ) ) {
 -                      wfSuppressWarnings();
 +                      MediaWiki\suppressWarnings();
                        $decomp = gzinflate( $serial );
 -                      wfRestoreWarnings();
 +                      MediaWiki\restoreWarnings();
  
                        if ( false !== $decomp ) {
                                $serial = $decomp;