Merge "Allow for dynamic TTLs in getWithSetCallback()"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 14 May 2015 03:23:36 +0000 (03:23 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 14 May 2015 03:23:36 +0000 (03:23 +0000)
includes/libs/objectcache/WANObjectCache.php
tests/phpunit/includes/objectcache/WANObjectCacheTest.php

index e1f64ba..0ca0f2e 100755 (executable)
@@ -307,10 +307,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
@@ -333,7 +336,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 );
@@ -426,7 +429,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 ) ) {
index 3161d18..3e284c8 100644 (file)
@@ -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 );