From: Aaron Schulz Date: Tue, 10 Jul 2018 23:26:43 +0000 (+0100) Subject: Make MultiWriteBagOStuff use the native merge() of each backend X-Git-Tag: 1.34.0-rc.0~4716^2 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/operations/recherche.php?a=commitdiff_plain;h=12200a2332c99a90cb47aa7cf15aee479921897a;p=lhc%2Fweb%2Fwiklou.git Make MultiWriteBagOStuff use the native merge() of each backend This lets backends that support CAS take advantage of it. Also fix race condition with merge() in asyncWrites mode where two threads might add to a list/set but the first request finishes after the second, which would erase an item during the set(). Bug: T198239 Change-Id: Ibd2539429746f12b4de74d0f031089cb80aa8b4b --- diff --git a/includes/libs/objectcache/MultiWriteBagOStuff.php b/includes/libs/objectcache/MultiWriteBagOStuff.php index 91f4167e32..043f8cbbe2 100644 --- a/includes/libs/objectcache/MultiWriteBagOStuff.php +++ b/includes/libs/objectcache/MultiWriteBagOStuff.php @@ -122,7 +122,7 @@ class MultiWriteBagOStuff extends BagOStuff { && $missIndexes && ( $flags & self::READ_VERIFIED ) == self::READ_VERIFIED ) { - // Backfill the value to the lower (and often larger) cache tiers + // Backfill the value to the higher (and often faster/smaller) cache tiers $this->doWrite( $missIndexes, $this->asyncWrites, 'set', $key, $value, self::UPGRADE_TTL ); @@ -171,6 +171,23 @@ class MultiWriteBagOStuff extends BagOStuff { return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'decr', $key, $value ); } + public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) { + $asyncWrites = ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) + ? false + : $this->asyncWrites; + + return $this->doWrite( + $this->cacheIndexes, + $asyncWrites, + 'merge', + $key, + $callback, + $exptime, + $attempts, + $flags + ); + } + public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' ) { // Only need to lock the first cache; also avoids deadlocks return $this->caches[0]->lock( $key, $timeout, $expiry, $rclass ); @@ -202,7 +219,7 @@ class MultiWriteBagOStuff extends BagOStuff { $ret = true; $args = array_slice( func_get_args(), 3 ); - if ( array_diff( $indexes, [ 0 ] ) && $asyncWrites ) { + if ( array_diff( $indexes, [ 0 ] ) && $asyncWrites && $method !== 'merge' ) { // Deep-clone $args to prevent misbehavior when something writes an // object to the BagOStuff then modifies it afterwards, e.g. T168040. $args = unserialize( serialize( $args ) );