X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Ffilebackend%2Flockmanager%2FMemcLockManager.php;h=81ce424b502e83996fc006ebc9f6be04d0cf0cf7;hb=32a1630ff2d6cda85d283df0cff3b0b805c67e27;hp=24d96e024b50f21364e6279fca16b20ea7381ef6;hpb=20e6ae299acc8cf42aa5040b7f0636850e8bdcd5;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/filebackend/lockmanager/MemcLockManager.php b/includes/filebackend/lockmanager/MemcLockManager.php index 24d96e024b..81ce424b50 100644 --- a/includes/filebackend/lockmanager/MemcLockManager.php +++ b/includes/filebackend/lockmanager/MemcLockManager.php @@ -37,17 +37,17 @@ */ class MemcLockManager extends QuorumLockManager { /** @var array Mapping of lock types to the type actually used */ - protected $lockTypeMap = array( + protected $lockTypeMap = [ self::LOCK_SH => self::LOCK_SH, self::LOCK_UW => self::LOCK_SH, self::LOCK_EX => self::LOCK_EX - ); + ]; /** @var array Map server names to MemcachedBagOStuff objects */ - protected $bagOStuffs = array(); + protected $bagOStuffs = []; /** @var array (server name => bool) */ - protected $serversUp = array(); + protected $serversUp = []; /** @var string Random UUID */ protected $session = ''; @@ -72,10 +72,10 @@ class MemcLockManager extends QuorumLockManager { $memcConfig = isset( $config['memcConfig'] ) ? $config['memcConfig'] - : array( 'class' => 'MemcachedPhpBagOStuff' ); + : [ 'class' => 'MemcachedPhpBagOStuff' ]; foreach ( $config['lockServers'] as $name => $address ) { - $params = array( 'servers' => array( $address ) ) + $memcConfig; + $params = [ 'servers' => [ $address ] ] + $memcConfig; $cache = ObjectCache::newFromParams( $params ); if ( $cache instanceof MemcachedBagOStuff ) { $this->bagOStuffs[$name] = $cache; @@ -90,9 +90,9 @@ class MemcLockManager extends QuorumLockManager { // @todo Change this code to work in one batch protected function getLocksOnServer( $lockSrv, array $pathsByType ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); - $lockedPaths = array(); + $lockedPaths = []; foreach ( $pathsByType as $type => $paths ) { $status->merge( $this->doGetLocksOnServer( $lockSrv, $paths, $type ) ); if ( $status->isOK() ) { @@ -112,7 +112,7 @@ class MemcLockManager extends QuorumLockManager { // @todo Change this code to work in one batch protected function freeLocksOnServer( $lockSrv, array $pathsByType ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); foreach ( $pathsByType as $type => $paths ) { $status->merge( $this->doFreeLocksOnServer( $lockSrv, $paths, $type ) ); @@ -126,13 +126,13 @@ class MemcLockManager extends QuorumLockManager { * @param string $lockSrv * @param array $paths * @param string $type - * @return Status + * @return StatusValue */ protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); $memc = $this->getCache( $lockSrv ); - $keys = array_map( array( $this, 'recordKeyForPath' ), $paths ); // lock records + $keys = array_map( [ $this, 'recordKeyForPath' ], $paths ); // lock records // Lock all of the active lock record keys... if ( !$this->acquireMutexes( $memc, $keys ) ) { @@ -202,13 +202,13 @@ class MemcLockManager extends QuorumLockManager { * @param string $lockSrv * @param array $paths * @param string $type - * @return Status + * @return StatusValue */ protected function doFreeLocksOnServer( $lockSrv, array $paths, $type ) { - $status = Status::newGood(); + $status = StatusValue::newGood(); $memc = $this->getCache( $lockSrv ); - $keys = array_map( array( $this, 'recordKeyForPath' ), $paths ); // lock records + $keys = array_map( [ $this, 'recordKeyForPath' ], $paths ); // lock records // Lock all of the active lock record keys... if ( !$this->acquireMutexes( $memc, $keys ) ) { @@ -254,10 +254,10 @@ class MemcLockManager extends QuorumLockManager { /** * @see QuorumLockManager::releaseAllLocks() - * @return Status + * @return StatusValue */ protected function releaseAllLocks() { - return Status::newGood(); // not supported + return StatusValue::newGood(); // not supported } /** @@ -276,6 +276,7 @@ class MemcLockManager extends QuorumLockManager { * @return MemcachedBagOStuff|null */ protected function getCache( $lockSrv ) { + /** @var BagOStuff $memc */ $memc = null; if ( isset( $this->bagOStuffs[$lockSrv] ) ) { $memc = $this->bagOStuffs[$lockSrv]; @@ -298,14 +299,14 @@ class MemcLockManager extends QuorumLockManager { * @return string */ protected function recordKeyForPath( $path ) { - return implode( ':', array( __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ) ); + return implode( ':', [ __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ] ); } /** * @return array An empty lock structure for a key */ protected static function newLockArray() { - return array( self::LOCK_SH => array(), self::LOCK_EX => array() ); + return [ self::LOCK_SH => [], self::LOCK_EX => [] ]; } /** @@ -328,7 +329,7 @@ class MemcLockManager extends QuorumLockManager { * @return bool */ protected function acquireMutexes( MemcachedBagOStuff $memc, array $keys ) { - $lockedKeys = array(); + $lockedKeys = []; // 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. @@ -337,20 +338,21 @@ class MemcLockManager extends QuorumLockManager { // 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 + $loop = new WaitConditionLoop( + function () use ( $memc, $keys, &$lockedKeys ) { + foreach ( array_diff( $keys, $lockedKeys ) as $key ) { + if ( $memc->add( "$key:mutex", 1, 180 ) ) { // lock record + $lockedKeys[] = $key; + } } - } - } while ( count( $lockedKeys ) < count( $keys ) && ( microtime( true ) - $start ) <= 3 ); + + return array_diff( $keys, $lockedKeys ) + ? WaitConditionLoop::CONDITION_CONTINUE + : true; + }, + 3.0 // timeout + ); + $loop->invoke(); if ( count( $lockedKeys ) != count( $keys ) ) { $this->releaseMutexes( $memc, $lockedKeys ); // failed; release what was locked @@ -376,8 +378,8 @@ class MemcLockManager extends QuorumLockManager { function __destruct() { while ( count( $this->locksHeld ) ) { foreach ( $this->locksHeld as $path => $locks ) { - $this->doUnlock( array( $path ), self::LOCK_EX ); - $this->doUnlock( array( $path ), self::LOCK_SH ); + $this->doUnlock( [ $path ], self::LOCK_EX ); + $this->doUnlock( [ $path ], self::LOCK_SH ); } } }