Merge "rdbms: clean up $groups logic in LoadBalancer and expand comments"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 5 Jul 2019 22:00:09 +0000 (22:00 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 5 Jul 2019 22:00:09 +0000 (22:00 +0000)
1  2 
includes/libs/rdbms/database/DBConnRef.php
tests/phpunit/tests/MediaWikiTestCaseTest.php

@@@ -5,8 -5,23 +5,23 @@@ namespace Wikimedia\Rdbms
  use InvalidArgumentException;
  
  /**
-  * Helper class to handle automatically marking connections as reusable (via RAII pattern)
-  * as well handling deferring the actual network connection until the handle is used
+  * Helper class used for automatically marking an IDatabase connection as reusable (once it no
+  * longer matters which DB domain is selected) and for deferring the actual network connection
+  *
+  * This uses an RAII-style pattern where calling code is expected to keep the returned reference
+  * handle as a function variable that falls out of scope when no longer needed. This avoids the
+  * need for matching reuseConnection() calls for every "return" statement as well as the tedious
+  * use of try/finally.
+  *
+  * @par Example:
+  * @code
+  *     function getRowData() {
+  *         $conn = $this->lb->getConnectedRef( DB_REPLICA );
+  *         $row = $conn->select( ... );
+  *         return $row ? (array)$row : false;
+  *         // $conn falls out of scope and $this->lb->reuseConnection() gets called
+  *     }
+  * @endcode
   *
   * @ingroup Database
   * @since 1.22
@@@ -28,7 -43,7 +43,7 @@@ class DBConnRef implements IDatabase 
  
        /**
         * @param ILoadBalancer $lb Connection manager for $conn
 -       * @param Database|array $conn Database or (server index, query groups, domain, flags)
 +       * @param IDatabase|array $conn Database or (server index, query groups, domain, flags)
         * @param int $role The type of connection asked for; one of DB_MASTER/DB_REPLICA
         * @internal This method should not be called outside of LoadBalancer
         */
                return $this->__call( __FUNCTION__, func_get_args() );
        }
  
 +      public function onAtomicSectionCancel( callable $callback, $fname = __METHOD__ ) {
 +              return $this->__call( __FUNCTION__, func_get_args() );
 +      }
 +
        public function setTransactionListener( $name, callable $callback = null ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@@ -167,7 -167,7 +167,7 @@@ class MediaWikiTestCaseTest extends Med
  
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                $lb = $lbFactory->newMainLB();
-               $db = $lb->getConnection( DB_REPLICA, DBO_TRX );
+               $db = $lb->getConnection( DB_REPLICA );
  
                // sanity
                $this->assertNotSame( $this->db, $db );
                $this->assertSame( 'TEST', $value, 'Copied Data' );
        }
  
 +      public function testResetServices() {
 +              $services = MediaWikiServices::getInstance();
 +
 +              // override a service instance
 +              $myReadOnlyMode = $this->getMockBuilder( ReadOnlyMode::class )
 +                      ->disableOriginalConstructor()
 +                      ->getMock();
 +              $this->setService( 'ReadOnlyMode', $myReadOnlyMode );
 +
 +              // sanity check
 +              $this->assertSame( $myReadOnlyMode, $services->getService( 'ReadOnlyMode' ) );
 +
 +              // define a custom service
 +              $services->defineService(
 +                      '_TEST_ResetService_Dummy',
 +                      function ( MediaWikiServices $services ) {
 +                              $conf = $services->getMainConfig();
 +                              return (object)[ 'lang' => $conf->get( 'LanguageCode' ) ];
 +                      }
 +              );
 +
 +              // sanity check
 +              $lang = $services->getMainConfig()->get( 'LanguageCode' );
 +              $dummy = $services->getService( '_TEST_ResetService_Dummy' );
 +              $this->assertSame( $lang, $dummy->lang );
 +
 +              // the actual test: change config, reset services.
 +              $this->setMwGlobals( 'wgLanguageCode', 'qqx' );
 +              $this->resetServices();
 +
 +              // the overridden service instance should still be there
 +              $this->assertSame( $myReadOnlyMode, $services->getService( 'ReadOnlyMode' ) );
 +
 +              // our custom service should have been re-created with the new language code
 +              $dummy2 = $services->getService( '_TEST_ResetService_Dummy' );
 +              $this->assertNotSame( $dummy2, $dummy );
 +              $this->assertSame( 'qqx', $dummy2->lang );
 +      }
 +
  }