00001 <?php
00002
00007 interface LoadMonitor {
00011 function __construct( $parent );
00012
00019 function scaleLoads( &$loads, $group = false, $wiki = false );
00020
00037 function postConnectionBackoff( $conn, $threshold );
00038
00042 function getLagTimes( $serverIndexes, $wiki );
00043 }
00044
00045
00051 class LoadMonitor_MySQL implements LoadMonitor {
00052 var $parent;
00053
00054 function __construct( $parent ) {
00055 $this->parent = $parent;
00056 }
00057
00058 function scaleLoads( &$loads, $group = false, $wiki = false ) {
00059 }
00060
00061 function getLagTimes( $serverIndexes, $wiki ) {
00062 wfProfileIn( __METHOD__ );
00063 $expiry = 5;
00064 $requestRate = 10;
00065
00066 global $wgMemc;
00067 if ( empty( $wgMemc ) )
00068 $wgMemc = wfGetMainCache();
00069
00070 $masterName = $this->parent->getServerName( 0 );
00071 $memcKey = wfMemcKey( 'lag_times', $masterName );
00072 $times = $wgMemc->get( $memcKey );
00073 if ( $times ) {
00074 # Randomly recache with probability rising over $expiry
00075 $elapsed = time() - $times['timestamp'];
00076 $chance = max( 0, ( $expiry - $elapsed ) * $requestRate );
00077 if ( mt_rand( 0, $chance ) != 0 ) {
00078 unset( $times['timestamp'] );
00079 wfProfileOut( __METHOD__ );
00080 return $times;
00081 }
00082 wfIncrStats( 'lag_cache_miss_expired' );
00083 } else {
00084 wfIncrStats( 'lag_cache_miss_absent' );
00085 }
00086
00087 # Cache key missing or expired
00088
00089 $times = array();
00090 foreach ( $serverIndexes as $i ) {
00091 if ($i == 0) { # Master
00092 $times[$i] = 0;
00093 } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
00094 $times[$i] = $conn->getLag();
00095 } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) {
00096 $times[$i] = $conn->getLag();
00097 }
00098 }
00099
00100 # Add a timestamp key so we know when it was cached
00101 $times['timestamp'] = time();
00102 $wgMemc->set( $memcKey, $times, $expiry );
00103
00104 # But don't give the timestamp to the caller
00105 unset($times['timestamp']);
00106 $lagTimes = $times;
00107
00108 wfProfileOut( __METHOD__ );
00109 return $lagTimes;
00110 }
00111
00112 function postConnectionBackoff( $conn, $threshold ) {
00113 if ( !$threshold ) {
00114 return 0;
00115 }
00116 $status = $conn->getStatus("Thread%");
00117 if ( $status['Threads_running'] > $threshold ) {
00118 return $status['Threads_connected'];
00119 } else {
00120 return 0;
00121 }
00122 }
00123 }
00124