MediaWiki  REL1_19
LoadMonitor.php
Go to the documentation of this file.
00001 <?php
00014 interface LoadMonitor {
00020         function __construct( $parent );
00021 
00028         function scaleLoads( &$loads, $group = false, $wiki = false );
00029 
00046         function postConnectionBackoff( $conn, $threshold );
00047 
00056         function getLagTimes( $serverIndexes, $wiki );
00057 }
00058 
00059 class LoadMonitor_Null implements LoadMonitor {
00060         function __construct( $parent ) {
00061         }
00062 
00063         function scaleLoads( &$loads, $group = false, $wiki = false ) {
00064         }
00065 
00066         function postConnectionBackoff( $conn, $threshold ) {
00067         }
00068 
00074         function getLagTimes( $serverIndexes, $wiki ) {
00075                 return array_fill_keys( $serverIndexes, 0 );
00076         }
00077 }
00078 
00085 class LoadMonitor_MySQL implements LoadMonitor {
00086 
00090         var $parent;
00091 
00095         function __construct( $parent ) {
00096                 $this->parent = $parent;
00097         }
00098 
00104         function scaleLoads( &$loads, $group = false, $wiki = false ) {
00105         }
00106 
00112         function getLagTimes( $serverIndexes, $wiki ) {
00113                 if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == 0 ) {
00114                         // Single server only, just return zero without caching
00115                         return array( 0 => 0 );
00116                 }
00117 
00118                 wfProfileIn( __METHOD__ );
00119                 $expiry = 5;
00120                 $requestRate = 10;
00121 
00122                 global $wgMemc;
00123                 if ( empty( $wgMemc ) )
00124                         $wgMemc = wfGetMainCache();
00125 
00126                 $masterName = $this->parent->getServerName( 0 );
00127                 $memcKey = wfMemcKey( 'lag_times', $masterName );
00128                 $times = $wgMemc->get( $memcKey );
00129                 if ( $times ) {
00130                         # Randomly recache with probability rising over $expiry
00131                         $elapsed = time() - $times['timestamp'];
00132                         $chance = max( 0, ( $expiry - $elapsed ) * $requestRate );
00133                         if ( mt_rand( 0, $chance ) != 0 ) {
00134                                 unset( $times['timestamp'] );
00135                                 wfProfileOut( __METHOD__ );
00136                                 return $times;
00137                         }
00138                         wfIncrStats( 'lag_cache_miss_expired' );
00139                 } else {
00140                         wfIncrStats( 'lag_cache_miss_absent' );
00141                 }
00142 
00143                 # Cache key missing or expired
00144 
00145                 $times = array();
00146                 foreach ( $serverIndexes as $i ) {
00147                         if ($i == 0) { # Master
00148                                 $times[$i] = 0;
00149                         } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
00150                                 $times[$i] = $conn->getLag();
00151                         } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) {
00152                                 $times[$i] = $conn->getLag();
00153                         }
00154                 }
00155 
00156                 # Add a timestamp key so we know when it was cached
00157                 $times['timestamp'] = time();
00158                 $wgMemc->set( $memcKey, $times, $expiry );
00159 
00160                 # But don't give the timestamp to the caller
00161                 unset($times['timestamp']);
00162                 $lagTimes = $times;
00163 
00164                 wfProfileOut( __METHOD__ );
00165                 return $lagTimes;
00166         }
00167 
00173         function postConnectionBackoff( $conn, $threshold ) {
00174                 if ( !$threshold ) {
00175                         return 0;
00176                 }
00177                 $status = $conn->getMysqlStatus("Thread%");
00178                 if ( $status['Threads_running'] > $threshold ) {
00179                         $server = $conn->getProperty( 'mServer' );
00180                         wfLogDBError( "LB backoff from $server - Threads_running = {$status['Threads_running']}\n" );
00181                         return $status['Threads_connected'];
00182                 } else {
00183                         return 0;
00184                 }
00185         }
00186 }
00187