From 1a2f4b55aa665f65d3fe1db44e0d520e337211d7 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Wed, 22 May 2013 16:19:16 -0700 Subject: [PATCH] [Database] Tweaked LoadMonitor::getLagTimes() to further reduce stampedes Change-Id: I79e3232e3e87bb298ae1a3fe214fcd2506818884 --- includes/db/LoadMonitor.php | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/includes/db/LoadMonitor.php b/includes/db/LoadMonitor.php index 4b9eccea4b..519e2dfd0e 100644 --- a/includes/db/LoadMonitor.php +++ b/includes/db/LoadMonitor.php @@ -142,12 +142,12 @@ class LoadMonitor_MySQL implements LoadMonitor { $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; } @@ -157,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 ) { @@ -171,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; } /** -- 2.20.1