From 4db819011aa95f61de7f19d47ce8c280a0f9d9c0 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Mon, 11 May 2015 10:03:55 -0700 Subject: [PATCH] Allow for dynamic TTLs in getWithSetCallback() * This gives it better parity with BagOStuff::set() * Also updated some doc comments Change-Id: Ib94b97715fae901bac1750656e3dc7501919d6d2 --- includes/libs/objectcache/WANObjectCache.php | 13 ++++++++----- .../includes/objectcache/WANObjectCacheTest.php | 11 ++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/includes/libs/objectcache/WANObjectCache.php b/includes/libs/objectcache/WANObjectCache.php index 92bd0bdfa6..21a09e6c21 100755 --- a/includes/libs/objectcache/WANObjectCache.php +++ b/includes/libs/objectcache/WANObjectCache.php @@ -300,10 +300,13 @@ class WANObjectCache { /** * Method to fetch/regenerate cache keys * - * On cache miss, the key will be set to the callback result. + * On cache miss, the key will be set to the callback result, + * unless the callback returns false. The arguments supplied are: + * (current value or false, &$ttl) * The callback function returns the new value given the current - * value (false if not present). If false is returned, then nothing - * will be saved to cache. + * value (false if not present). Preemptive re-caching and $checkKeys + * can result in a non-false current value. The TTL of the new value + * can be set dynamically by altering $ttl in the callback (by reference). * * Usually, callbacks ignore the current value, but it can be used * to maintain "most recent X" values that come from time or sequence @@ -326,7 +329,7 @@ class WANObjectCache { * @code * $key = wfMemcKey( 'cat-recent-actions', $catId ); * // Function that derives the new key value given the old value - * $callback = function( $cValue ) { ... }; + * $callback = function( $cValue, &$ttl ) { ... }; * // Get the key value from cache or from source on cache miss; * // try to only let one cluster thread manage doing cache updates * $opts = array( 'lockTSE' => 5, 'lowTTL' => 10 ); @@ -419,7 +422,7 @@ class WANObjectCache { } // Generate the new value from the callback... - $value = call_user_func( $callback, $cValue ); + $value = call_user_func_array( $callback, array( $cValue, &$ttl ) ); // When delete() is called, writes are write-holed by the tombstone, // so use a special stash key to pass the new value around threads. if ( $value !== false && ( $isHot || $isTombstone ) ) { diff --git a/tests/phpunit/includes/objectcache/WANObjectCacheTest.php b/tests/phpunit/includes/objectcache/WANObjectCacheTest.php index 3161d18aca..3e284c8110 100644 --- a/tests/phpunit/includes/objectcache/WANObjectCacheTest.php +++ b/tests/phpunit/includes/objectcache/WANObjectCacheTest.php @@ -86,13 +86,22 @@ class WANObjectCacheTest extends MediaWikiTestCase { $cKey2 = wfRandomString(); $wasSet = 0; - $func = function() use ( &$wasSet, $value ) { ++$wasSet; return $value; }; + $func = function( $old, &$ttl ) use ( &$wasSet, $value ) { + ++$wasSet; + $ttl = 20; // override with another value + return $value; + }; $wasSet = 0; $v = $cache->getWithSetCallback( $key, $func, 30, array(), array( 'lockTSE' => 5 ) ); $this->assertEquals( $v, $value ); $this->assertEquals( 1, $wasSet, "Value regenerated" ); + $curTTL = null; + $v = $cache->get( $key, $curTTL ); + $this->assertLessThanOrEqual( 20, $curTTL, 'Current TTL between 19-20 (overriden)' ); + $this->assertGreaterThanOrEqual( 19, $curTTL, 'Current TTL between 19-20 (overriden)' ); + $wasSet = 0; $v = $cache->getWithSetCallback( $key, $func, 30, array(), array( 'lockTSE' => 5 ) ); $this->assertEquals( $v, $value ); -- 2.20.1