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