summaryrefslogtreecommitdiff
path: root/includes/db/LoadMonitor.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/db/LoadMonitor.php')
-rw-r--r--includes/db/LoadMonitor.php27
1 files changed, 18 insertions, 9 deletions
diff --git a/includes/db/LoadMonitor.php b/includes/db/LoadMonitor.php
index ad7b3b2f..519e2dfd 100644
--- a/includes/db/LoadMonitor.php
+++ b/includes/db/LoadMonitor.php
@@ -135,18 +135,19 @@ class LoadMonitor_MySQL implements LoadMonitor {
$requestRate = 10;
global $wgMemc;
- if ( empty( $wgMemc ) )
+ if ( empty( $wgMemc ) ) {
$wgMemc = wfGetMainCache();
+ }
$masterName = $this->parent->getServerName( 0 );
$memcKey = wfMemcKey( 'lag_times', $masterName );
$times = $wgMemc->get( $memcKey );
- if ( $times ) {
+ if ( is_array( $times ) ) {
# Randomly recache with probability rising over $expiry
$elapsed = time() - $times['timestamp'];
$chance = max( 0, ( $expiry - $elapsed ) * $requestRate );
if ( mt_rand( 0, $chance ) != 0 ) {
- unset( $times['timestamp'] );
+ unset( $times['timestamp'] ); // hide from caller
wfProfileOut( __METHOD__ );
return $times;
}
@@ -156,6 +157,17 @@ class LoadMonitor_MySQL implements LoadMonitor {
}
# Cache key missing or expired
+ if ( $wgMemc->add( "$memcKey:lock", 1, 10 ) ) {
+ # Let this process alone update the cache value
+ $unlocker = new ScopedCallback( function() use ( $wgMemc, $memcKey ) {
+ $wgMemc->delete( $memcKey );
+ } );
+ } elseif ( is_array( $times ) ) {
+ # Could not acquire lock but an old cache exists, so use it
+ unset( $times['timestamp'] ); // hide from caller
+ wfProfileOut( __METHOD__ );
+ return $times;
+ }
$times = array();
foreach ( $serverIndexes as $i ) {
@@ -170,14 +182,11 @@ class LoadMonitor_MySQL implements LoadMonitor {
# Add a timestamp key so we know when it was cached
$times['timestamp'] = time();
- $wgMemc->set( $memcKey, $times, $expiry );
-
- # But don't give the timestamp to the caller
- unset( $times['timestamp'] );
- $lagTimes = $times;
+ $wgMemc->set( $memcKey, $times, $expiry + 10 );
+ unset( $times['timestamp'] ); // hide from caller
wfProfileOut( __METHOD__ );
- return $lagTimes;
+ return $times;
}
/**