MediaWiki
REL1_20
|
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