aboutsummaryrefslogtreecommitdiffstats
path: root/includes/filerepo/backend/lockmanager
diff options
context:
space:
mode:
authorAaron <aschulz@wikimedia.org>2012-07-17 17:02:56 +0000
committerGerrit Code Review <gerrit@wikimedia.org>2012-07-17 17:02:56 +0000
commit090567090c9d94875ec48fff7de89c6362820bef (patch)
tree5fefe588f74a39ac690aa5e3eb9f15ee9c75e277 /includes/filerepo/backend/lockmanager
parent7d6d54df8a068a982c3c8f2ae1d188f3383ca9c5 (diff)
parent1d84790d890f5751a7eba04fb7d17f6720fae2a9 (diff)
downloadmediawikicore-090567090c9d94875ec48fff7de89c6362820bef.tar.gz
mediawikicore-090567090c9d94875ec48fff7de89c6362820bef.zip
Merge "[LockManager] Memc lockmanager improvements."
Diffstat (limited to 'includes/filerepo/backend/lockmanager')
-rw-r--r--includes/filerepo/backend/lockmanager/MemcLockManager.php15
1 files changed, 14 insertions, 1 deletions
diff --git a/includes/filerepo/backend/lockmanager/MemcLockManager.php b/includes/filerepo/backend/lockmanager/MemcLockManager.php
index 79696b2f8ca0..9e81dbfdb992 100644
--- a/includes/filerepo/backend/lockmanager/MemcLockManager.php
+++ b/includes/filerepo/backend/lockmanager/MemcLockManager.php
@@ -92,7 +92,7 @@ class MemcLockManager extends QuorumLockManager {
$met = ini_get( 'max_execution_time' ); // this is 0 in CLI mode
$this->lockExpiry = $met ? 2*(int)$met : 2*3600;
- $this->session = wfRandomString( 31 );
+ $this->session = wfRandomString( 32 );
}
/**
@@ -264,11 +264,24 @@ class MemcLockManager extends QuorumLockManager {
protected function acquireMutexes( MemcachedBagOStuff $memc, array $keys ) {
$lockedKeys = array();
+ // Acquire the keys in lexicographical order, to avoid deadlock problems.
+ // If P1 is waiting to acquire a key P2 has, P2 can't also be waiting for a key P1 has.
+ sort( $keys );
+
+ // Try to quickly loop to acquire the keys, but back off after a few rounds.
+ // This reduces memcached spam, especially in the rare case where a server acquires
+ // some lock keys and dies without releasing them. Lock keys expire after a few minutes.
+ $rounds = 0;
$start = microtime( true );
do {
+ if ( ( ++$rounds % 4 ) == 0 ) {
+ usleep( 1000*50 ); // 50 ms
+ }
foreach ( array_diff( $keys, $lockedKeys ) as $key ) {
if ( $memc->add( "$key:mutex", 1, 180 ) ) { // lock record
$lockedKeys[] = $key;
+ } else {
+ continue; // acquire in order
}
}
} while ( count( $lockedKeys ) < count( $keys ) && ( microtime( true ) - $start ) <= 6 );