Merge "Don't throw an exception when waiting for replication times out"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 4 Sep 2018 02:20:12 +0000 (02:20 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 4 Sep 2018 02:20:12 +0000 (02:20 +0000)
1  2 
includes/GlobalFunctions.php
includes/installer/DatabaseUpdater.php
includes/installer/MysqlUpdater.php
includes/jobqueue/jobs/RefreshLinksJob.php
maintenance/updateSpecialPages.php

@@@ -30,7 -30,6 +30,6 @@@ use MediaWiki\Session\SessionManager
  use MediaWiki\MediaWikiServices;
  use MediaWiki\Shell\Shell;
  use Wikimedia\ScopedCallback;
- use Wikimedia\Rdbms\DBReplicationWaitError;
  use Wikimedia\WrappedString;
  
  /**
@@@ -2674,6 -2673,28 +2673,6 @@@ function wfGetPrecompiledData( $name ) 
        return false;
  }
  
 -/**
 - * @since 1.32
 - * @param string[] $data Array with string keys/values to export
 - * @param string $header
 - * @return string PHP code
 - */
 -function wfMakeStaticArrayFile( array $data, $header = 'Automatically generated' ) {
 -      $format = "\t%s => %s,\n";
 -      $code = "<?php\n"
 -              . "// " . implode( "\n// ", explode( "\n", $header ) ) . "\n"
 -              . "return [\n";
 -      foreach ( $data as $key => $value ) {
 -              $code .= sprintf(
 -                      $format,
 -                      var_export( $key, true ),
 -                      var_export( $value, true )
 -              );
 -      }
 -      $code .= "];\n";
 -      return $code;
 -}
 -
  /**
   * Make a cache key for the local wiki.
   *
@@@ -2922,17 -2943,13 +2921,13 @@@ function wfGetNull() 
   * @param float|null $ifWritesSince Only wait if writes were done since this UNIX timestamp
   * @param string|bool $wiki Wiki identifier accepted by wfGetLB
   * @param string|bool $cluster Cluster name accepted by LBFactory. Default: false.
-  * @param int|null $timeout Max wait time. Default: 1 day (cli), ~10 seconds (web)
+  * @param int|null $timeout Max wait time. Default: 60 seconds (cli), 1 second (web)
   * @return bool Success (able to connect and no timeouts reached)
   * @deprecated since 1.27 Use LBFactory::waitForReplication
   */
  function wfWaitForSlaves(
        $ifWritesSince = null, $wiki = false, $cluster = false, $timeout = null
  ) {
-       if ( $timeout === null ) {
-               $timeout = wfIsCLI() ? 60 : 10;
-       }
        if ( $cluster === '*' ) {
                $cluster = false;
                $wiki = false;
                $wiki = wfWikiID();
        }
  
-       try {
-               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               $lbFactory->waitForReplication( [
-                       'wiki' => $wiki,
-                       'cluster' => $cluster,
-                       'timeout' => $timeout,
-                       // B/C: first argument used to be "max seconds of lag"; ignore such values
-                       'ifWritesSince' => ( $ifWritesSince > 1e9 ) ? $ifWritesSince : null
-               ] );
-       } catch ( DBReplicationWaitError $e ) {
-               return false;
+       $opts = [
+               'wiki' => $wiki,
+               'cluster' => $cluster,
+               // B/C: first argument used to be "max seconds of lag"; ignore such values
+               'ifWritesSince' => ( $ifWritesSince > 1e9 ) ? $ifWritesSince : null
+       ];
+       if ( $timeout !== null ) {
+               $opts['timeout'] = $timeout;
        }
  
-       return true;
+       $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+       return $lbFactory->waitForReplication( $opts );
  }
  
  /**
@@@ -3097,7 -3112,6 +3090,7 @@@ function wfBCP47( $code ) 
  /**
   * Get a specific cache object.
   *
 + * @deprecated since 1.32, use ObjectCache::getInstance() instead
   * @param int|string $cacheType A CACHE_* constants, or other key in $wgObjectCaches
   * @return BagOStuff
   */
@@@ -3108,11 -3122,11 +3101,11 @@@ function wfGetCache( $cacheType ) 
  /**
   * Get the main cache object
   *
 + * @deprecated since 1.32, use ObjectCache::getLocalClusterInstance() instead
   * @return BagOStuff
   */
  function wfGetMainCache() {
 -      global $wgMainCacheType;
 -      return ObjectCache::getInstance( $wgMainCacheType );
 +      return ObjectCache::getLocalClusterInstance();
  }
  
  /**
@@@ -34,6 -34,8 +34,8 @@@ require_once __DIR__ . '/../../maintena
   * @since 1.17
   */
  abstract class DatabaseUpdater {
+       const REPLICATION_WAIT_TIMEOUT = 300;
        /**
         * Array of updates to perform on the database
         *
                        flush();
                        if ( $ret !== false ) {
                                $updatesDone[] = $origParams;
-                               $lbFactory->waitForReplication();
+                               $lbFactory->waitForReplication( [ 'timeout' => self::REPLICATION_WAIT_TIMEOUT ] );
                        } else {
                                $updatesSkipped[] = [ $func, $params, $origParams ];
                        }
                }
        }
  
 -      /**
 -       * Updates the timestamps in the transcache table
 -       * @return bool
 -       */
 -      protected function doUpdateTranscacheField() {
 -              if ( $this->updateRowExists( 'convert transcache field' ) ) {
 -                      $this->output( "...transcache tc_time already converted.\n" );
 -
 -                      return true;
 -              }
 -
 -              return $this->applyPatch( 'patch-tc-timestamp.sql', false,
 -                      "Converting tc_time from UNIX epoch to MediaWiki timestamp" );
 -      }
 -
        /**
         * Update CategoryLinks collation
         */
@@@ -84,6 -84,7 +84,6 @@@ class MysqlUpdater extends DatabaseUpda
                        [ 'doUserGroupsUpdate' ],
                        [ 'addField', 'site_stats', 'ss_total_pages', 'patch-ss_total_articles.sql' ],
                        [ 'addTable', 'user_newtalk', 'patch-usernewtalk.sql' ],
 -                      [ 'addTable', 'transcache', 'patch-transcache.sql' ],
                        [ 'addField', 'interwiki', 'iw_trans', 'patch-interwiki-trans.sql' ],
  
                        // 1.6
                        [ 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ],
                        [ 'addIndex', 'change_tag', 'change_tag_rc_tag', 'patch-change_tag-indexes.sql' ],
                        [ 'addField', 'redirect', 'rd_interwiki', 'patch-rd_interwiki.sql' ],
 -                      [ 'doUpdateTranscacheField' ],
                        [ 'doUpdateMimeMinorField' ],
  
                        // 1.17
                        [ 'renameIndex', 'querycache_info', 'qci_type', 'PRIMARY', false,
                                'patch-querycache_info-fix-pk.sql' ],
                        [ 'renameIndex', 'site_stats', 'ss_row_id', 'PRIMARY', false, 'patch-site_stats-fix-pk.sql' ],
 -                      [ 'renameIndex', 'transcache', 'tc_url_idx', 'PRIMARY', false, 'patch-transcache-fix-pk.sql' ],
                        [ 'renameIndex', 'user_former_groups', 'ufg_user_group', 'PRIMARY', false,
                                'patch-user_former_groups-fix-pk.sql' ],
                        [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
                                'patch-protected_titles-fix-pk.sql' ],
                        [ 'renameIndex', 'site_identifiers', 'site_ids_type', 'PRIMARY', false,
                                'patch-site_identifiers-fix-pk.sql' ],
 +                      [ 'addIndex', 'recentchanges', 'rc_this_oldid', 'patch-recentchanges-rc_this_oldid-index.sql' ],
 +                      [ 'dropTable', 'transcache' ],
                ];
        }
  
                                $count = ( $count + 1 ) % 100;
                                if ( $count == 0 ) {
                                        $lbFactory = $services->getDBLoadBalancerFactory();
-                                       $lbFactory->waitForReplication( [ 'wiki' => wfWikiID() ] );
+                                       $lbFactory->waitForReplication( [
+                                               'wiki' => wfWikiID(), 'timeout' => self::REPLICATION_WAIT_TIMEOUT ] );
                                }
                                $this->db->insert( 'templatelinks',
                                        [
@@@ -21,7 -21,6 +21,6 @@@
   * @ingroup JobQueue
   */
  use MediaWiki\MediaWikiServices;
- use Wikimedia\Rdbms\DBReplicationWaitError;
  
  /**
   * Job to update link tables for pages
@@@ -89,13 -88,11 +88,11 @@@ class RefreshLinksJob extends Job 
                        // 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( $this->params['range'] ) ) {
-                               try {
-                                       $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-                                       $lbFactory->waitForReplication( [
+                               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+                               if ( !$lbFactory->waitForReplication( [
                                                'wiki'    => wfWikiID(),
                                                'timeout' => self::LAG_WAIT_TIMEOUT
-                                       ] );
-                               } catch ( DBReplicationWaitError $e ) { // only try so hard
+                               ] ) ) { // only try so hard
                                        $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
                                        $stats->increment( 'refreshlinks.lag_wait_failed' );
                                }
                $dbw = $lbFactory->getMainLB()->getConnection( DB_MASTER );
                /** @noinspection PhpUnusedLocalVariableInspection */
                $scopedLock = LinksUpdate::acquirePageLock( $dbw, $page->getId(), 'job' );
 +              if ( $scopedLock === null ) {
 +                      // Another job is already updating the page, likely for an older revision (T170596).
 +                      $this->setLastError( 'LinksUpdate already running for this page, try again later.' );
 +                      return false;
 +              }
                // Get the latest ID *after* acquirePageLock() flushed the transaction.
                // This is used to detect edits/moves after loadPageData() but before the scope lock.
                // The works around the chicken/egg problem of determining the scope lock key.
@@@ -25,7 -25,6 +25,6 @@@
  require_once __DIR__ . '/Maintenance.php';
  
  use MediaWiki\MediaWikiServices;
- use Wikimedia\Rdbms\DBReplicationWaitError;
  
  /**
   * Maintenance script to update cached special pages.
@@@ -66,8 -65,7 +65,8 @@@ class UpdateSpecialPages extends Mainte
                                continue;
                        }
  
 -                      $specialObj = SpecialPageFactory::getPage( $special );
 +                      $specialObj = MediaWikiServices::getInstance()->getSpecialPageFactory()->
 +                              getPage( $special );
                        if ( !$specialObj ) {
                                $this->output( "No such special page: $special\n" );
                                exit;
                        $this->output( "Reconnected\n\n" );
                }
                // Wait for the replica DB to catch up
-               try {
-                       $lbFactory->waitForReplication();
-               } catch ( DBReplicationWaitError $e ) {
-                       // ignore
-               }
+               $lbFactory->waitForReplication();
        }
  
        public function doSpecialPageCacheUpdates( $dbw ) {