MediaWiki  REL1_20
LoadMonitor.php
Go to the documentation of this file.
00001 <?php
00029 interface LoadMonitor {
00035         function __construct( $parent );
00036 
00043         function scaleLoads( &$loads, $group = false, $wiki = false );
00044 
00061         function postConnectionBackoff( $conn, $threshold );
00062 
00071         function getLagTimes( $serverIndexes, $wiki );
00072 }
00073 
00074 class LoadMonitor_Null implements LoadMonitor {
00075         function __construct( $parent ) {
00076         }
00077 
00078         function scaleLoads( &$loads, $group = false, $wiki = false ) {
00079         }
00080 
00081         function postConnectionBackoff( $conn, $threshold ) {
00082         }
00083 
00089         function getLagTimes( $serverIndexes, $wiki ) {
00090                 return array_fill_keys( $serverIndexes, 0 );
00091         }
00092 }
00093 
00100 class LoadMonitor_MySQL implements LoadMonitor {
00101 
00105         var $parent;
00106 
00110         function __construct( $parent ) {
00111                 $this->parent = $parent;
00112         }
00113 
00119         function scaleLoads( &$loads, $group = false, $wiki = false ) {
00120         }
00121 
00127         function getLagTimes( $serverIndexes, $wiki ) {
00128                 if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == 0 ) {
00129                         // Single server only, just return zero without caching
00130                         return array( 0 => 0 );
00131                 }
00132 
00133                 wfProfileIn( __METHOD__ );
00134                 $expiry = 5;
00135                 $requestRate = 10;
00136 
00137                 global $wgMemc;
00138                 if ( empty( $wgMemc ) )
00139                         $wgMemc = wfGetMainCache();
00140 
00141                 $masterName = $this->parent->getServerName( 0 );
00142                 $memcKey = wfMemcKey( 'lag_times', $masterName );
00143                 $times = $wgMemc->get( $memcKey );
00144                 if ( $times ) {
00145                         # Randomly recache with probability rising over $expiry
00146                         $elapsed = time() - $times['timestamp'];
00147                         $chance = max( 0, ( $expiry - $elapsed ) * $requestRate );
00148                         if ( mt_rand( 0, $chance ) != 0 ) {
00149                                 unset( $times['timestamp'] );
00150                                 wfProfileOut( __METHOD__ );
00151                                 return $times;
00152                         }
00153                         wfIncrStats( 'lag_cache_miss_expired' );
00154                 } else {
00155                         wfIncrStats( 'lag_cache_miss_absent' );
00156                 }
00157 
00158                 # Cache key missing or expired
00159 
00160                 $times = array();
00161                 foreach ( $serverIndexes as $i ) {
00162                         if ($i == 0) { # Master
00163                                 $times[$i] = 0;
00164                         } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
00165                                 $times[$i] = $conn->getLag();
00166                         } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) {
00167                                 $times[$i] = $conn->getLag();
00168                         }
00169                 }
00170 
00171                 # Add a timestamp key so we know when it was cached
00172                 $times['timestamp'] = time();
00173                 $wgMemc->set( $memcKey, $times, $expiry );
00174 
00175                 # But don't give the timestamp to the caller
00176                 unset($times['timestamp']);
00177                 $lagTimes = $times;
00178 
00179                 wfProfileOut( __METHOD__ );
00180                 return $lagTimes;
00181         }
00182 
00188         function postConnectionBackoff( $conn, $threshold ) {
00189                 if ( !$threshold ) {
00190                         return 0;
00191                 }
00192                 $status = $conn->getMysqlStatus("Thread%");
00193                 if ( $status['Threads_running'] > $threshold ) {
00194                         $server = $conn->getProperty( 'mServer' );
00195                         wfLogDBError( "LB backoff from $server - Threads_running = {$status['Threads_running']}\n" );
00196                         return $status['Threads_connected'];
00197                 } else {
00198                         return 0;
00199                 }
00200         }
00201 }
00202