From: Aaron Schulz Date: Mon, 28 Sep 2015 21:07:01 +0000 (-0700) Subject: Fixed sanity cache clear in User::saveSettings() X-Git-Tag: 1.31.0-rc.0~9695^2 X-Git-Url: http://git.cyclocoop.org//%22javascript:ModifierStyle%28%27%22.%24id.%22%27%29/%22?a=commitdiff_plain;h=b23e0b0a835fa84031442b8b3b313860a6affadf;p=lhc%2Fweb%2Fwiklou.git Fixed sanity cache clear in User::saveSettings() * This works by adding a refresh mode to clearSharedCache() when we want to purge the cache in case it might stale to avoid further CAS errors. Because an exception will be thrown, the usual DB callback will not get fired, so avoid using commit hooks when doing these cache purges. * Also lowered the tombstone TTL for such purges, since no data actually changed. Bug: T114023 Change-Id: Iaad87b4ed24733dac40bc9607d3c97c940710087 --- diff --git a/includes/User.php b/includes/User.php index faf1bdc48c..168c4aceb4 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1484,11 +1484,12 @@ class User implements IDBAccessObject { if ( $success ) { $this->mTouched = $newTouched; + $this->clearSharedCache(); + } else { + // Clears on failure too since that is desired if the cache is stale + $this->clearSharedCache( 'refresh' ); } - // Clears on failure too since that is desired if the cache is stale - $this->clearSharedCache(); - return $success; } @@ -2282,22 +2283,29 @@ class User implements IDBAccessObject { } /** - * Clear user data from memcached. - * Use after applying fun updates to the database; caller's + * Clear user data from memcached + * + * Use after applying updates to the database; caller's * responsibility to update user_touched if appropriate. * * Called implicitly from invalidateCache() and saveSettings(). + * + * @param string $mode Use 'refresh' to clear now; otherwise before DB commit */ - public function clearSharedCache() { + public function clearSharedCache( $mode = 'changed' ) { $id = $this->getId(); if ( !$id ) { return; } $key = wfMemcKey( 'user', 'id', $id ); - wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $key ) { - ObjectCache::getMainWANInstance()->delete( $key ); - } ); + if ( $mode === 'refresh' ) { + ObjectCache::getMainWANInstance()->delete( $key, 1 ); + } else { + wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle( function() use ( $key ) { + ObjectCache::getMainWANInstance()->delete( $key ); + } ); + } } /** @@ -3702,7 +3710,7 @@ class User implements IDBAccessObject { if ( !$dbw->affectedRows() ) { // Maybe the problem was a missed cache update; clear it to be safe - $this->clearSharedCache(); + $this->clearSharedCache( 'refresh' ); // User was changed in the meantime or loaded with stale data $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'slave'; throw new MWException(