* @subpackage Parser
[lhc/web/wiklou.git] / includes / LoadBalancer.php
index 69b5cd3..8c9aa64 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 /**
  *
+ * @package MediaWiki
  */
 
 /**
@@ -29,17 +30,18 @@ define( 'DB_ASKSQL_R', 1002 );    # Special:Asksql read
 define( 'DB_WATCHLIST_R', 1004 ); # Watchlist read
 define( 'DB_TASK_LAST', 1004) ;   # Last in list
 
-define( 'MASTER_WAIT_TIMEOUT', 15 ); # Time to wait for a slave to synchronise
-
 /**
  * Database load balancing object
+ *
  * @todo document
+ * @package MediaWiki
  */
 class LoadBalancer {
        /* private */ var $mServers, $mConnections, $mLoads;
        /* private */ var $mFailFunction;
        /* private */ var $mForce, $mReadIndex, $mLastIndex;
-       /* private */ var $mWaitForFile, $mWaitForPos;
+       /* private */ var $mWaitForFile, $mWaitForPos, $mWaitTimeout;
+       /* private */ var $mLaggedSlaveMode;
 
        function LoadBalancer()
        {
@@ -51,14 +53,14 @@ class LoadBalancer {
                $this->mLastIndex = -1;
        }
 
-       function newFromParams( $servers, $failFunction = false )
+       function newFromParams( $servers, $failFunction = false, $waitTimeout = 10 )
        {
                $lb = new LoadBalancer;
                $lb->initialise( $servers, $failFunction = false );
                return $lb;
        }
 
-       function initialise( $servers, $failFunction = false )
+       function initialise( $servers, $failFunction = false, $waitTimeout = 10 )
        {
                $this->mServers = $servers;
                $this->mFailFunction = $failFunction;
@@ -70,6 +72,8 @@ class LoadBalancer {
                $this->mLoads = array();
                $this->mWaitForFile = false;
                $this->mWaitForPos = false;
+               $this->mWaitTimeout = $waitTimeout;
+               $this->mLaggedSlaveMode = false;
 
                foreach( $servers as $i => $server ) {
                        $this->mLoads[$i] = $server['load'];
@@ -161,8 +165,7 @@ class LoadBalancer {
 
                        if ( $this->mReadIndex > 0 ) {
                                if ( !$this->doWait( $this->mReadIndex ) ) {
-                                       # Use master instead
-                                       $this->mReadIndex = 0;
+                                       $this->mLaggedSlaveMode = true;
                                }
                        } 
                }
@@ -188,9 +191,9 @@ class LoadBalancer {
                }
 
                if ( !$retVal && $this->isOpen( $index ) ) {
-                       $conn =& $this->mConnections( $index );
+                       $conn =& $this->mConnections[$index];
                        wfDebug( "Waiting for slave #$index to catch up...\n" );
-                       $result = $conn->masterPosWait( $this->mWaitForFile, $this->mWaitForPos, MASTER_WAIT_TIMEOUT );
+                       $result = $conn->masterPosWait( $this->mWaitForFile, $this->mWaitForPos, $this->mWaitTimeout );
 
                        if ( $result == -1 || is_null( $result ) ) {
                                # Timed out waiting for slave, use master instead
@@ -300,15 +303,19 @@ class LoadBalancer {
         * @private
         */
        function reallyOpenConnection( &$server ) {
-                       extract( $server );
-                       # Get class for this database type
-                       $class = 'Database' . ucfirst( $type );
-                       if ( !class_exists( $class ) ) {
-                               require_once( "$class.php" );
-                       }
+               if( !is_array( $server ) ) {
+                       wfDebugDieBacktrace( 'You must update your load-balancing configuration. See DefaultSettings.php entry for $wgDBservers.' );
+               }
+               
+               extract( $server );
+               # Get class for this database type
+               $class = 'Database' . ucfirst( $type );
+               if ( !class_exists( $class ) ) {
+                       require_once( "$class.php" );
+               }
 
-                       # Create object
-                       return new $class( $host, $user, $password, $dbname, 1, $flags );
+               # Create object
+               return new $class( $host, $user, $password, $dbname, 1, $flags );
        }
        
        function reportConnectionError( &$conn )
@@ -395,7 +402,8 @@ class LoadBalancer {
        function closeAll() {
                foreach( $this->mConnections as $i => $conn ) {
                        if ( $this->isOpen( $i ) ) {
-                               $conn->close();
+                               // Need to use this syntax because $conn is a copy not a reference
+                               $this->mConnections[$i]->close();
                        }
                }
        }
@@ -403,8 +411,17 @@ class LoadBalancer {
        function commitAll() {
                foreach( $this->mConnections as $i => $conn ) {
                        if ( $this->isOpen( $i ) ) {
-                               $conn->immediateCommit();
+                               // Need to use this syntax because $conn is a copy not a reference
+                               $this->mConnections[$i]->immediateCommit();
                        }
                }
        }
+
+       function waitTimeout( $value = NULL ) {
+               return wfSetVar( $this->mWaitTimeout, $value );
+       }
+
+       function getLaggedSlaveMode() {
+               return $this->mLaggedSlaveMode;
+       }
 }