objectcache: Add BagOStuff::getWithSetCallback() convenience method
authorAaron Schulz <aschulz@wikimedia.org>
Sat, 3 Oct 2015 19:37:28 +0000 (12:37 -0700)
committerTimo Tijhof <krinklemail@gmail.com>
Tue, 6 Oct 2015 00:26:32 +0000 (17:26 -0700)
Change-Id: I9cc162ff1cc48c1c500f2999327bd18ba235bfd0

includes/libs/objectcache/BagOStuff.php
tests/phpunit/includes/objectcache/BagOStuffTest.php

index 31bffd4..647d938 100644 (file)
@@ -87,6 +87,33 @@ abstract class BagOStuff implements LoggerAwareInterface {
                $this->debugMode = $bool;
        }
 
+       /**
+        * Get an item with the given key, regenerating and setting it if not found
+        *
+        * If the callback returns false, then nothing is stored.
+        *
+        * @param string $key
+        * @param int $ttl Time-to-live (seconds)
+        * @param callable $callback Callback that derives the new value
+        * @return mixed The cached value if found or the result of $callback otherwise
+        * @since 1.27
+        */
+       final public function getWithSetCallback( $key, $ttl, $callback ) {
+               $value = $this->get( $key );
+
+               if ( $value === false ) {
+                       if ( !is_callable( $callback ) ) {
+                               throw new InvalidArgumentException( "Invalid cache miss callback provided." );
+                       }
+                       $value = call_user_func( $callback );
+                       if ( $value !== false ) {
+                               $this->set( $key, $value, $ttl );
+                       }
+               }
+
+               return $value;
+       }
+
        /**
         * Get an item with the given key
         *
index dbccd28..b9fe490 100644 (file)
@@ -120,6 +120,23 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->assertEquals( $this->cache->get( $key ), $value );
        }
 
+       /**
+        * @covers BagOStuff::getWithSetCallback
+        */
+       public function testGetWithSetCallback() {
+               $key = wfMemcKey( 'test' );
+               $value = $this->cache->getWithSetCallback(
+                       $key,
+                       30,
+                       function () {
+                               return 'hello kitty';
+                       }
+               );
+
+               $this->assertEquals( 'hello kitty', $value );
+               $this->assertEquals( $value, $this->cache->get( $key ) );
+       }
+
        /**
         * @covers BagOStuff::incr
         */