]> git.mxchange.org Git - friendica.git/commitdiff
friendica-5847 Console Cache List command doesn't work
authorPhilipp Holzer <admin@philipp.info>
Sat, 6 Oct 2018 22:27:54 +0000 (00:27 +0200)
committerPhilipp Holzer <admin@philipp.info>
Sat, 6 Oct 2018 22:27:54 +0000 (00:27 +0200)
- Added $prefix to all CacheDriver
- Moved hostname magic to CacheDriver
- Added test for getAllKeys()

15 files changed:
src/Core/Cache.php
src/Core/Cache/AbstractCacheDriver.php
src/Core/Cache/ArrayCache.php
src/Core/Cache/DatabaseCacheDriver.php
src/Core/Cache/ICacheDriver.php
src/Core/Cache/MemcacheCacheDriver.php
src/Core/Cache/MemcachedCacheDriver.php
src/Core/Cache/RedisCacheDriver.php
src/Core/Console/Cache.php
tests/src/Core/Cache/ArrayCacheDriverTest.php
tests/src/Core/Cache/CacheTest.php
tests/src/Core/Cache/DatabaseCacheDriverTest.php
tests/src/Core/Cache/MemcacheCacheDriverTest.php
tests/src/Core/Cache/MemcachedCacheDriverTest.php
tests/src/Core/Cache/RedisCacheDriverTest.php

index ea7807031fde7389479dfb2bad49c1d342094e2c..7b9f6edd2c2ffbefba7e0a5d093ebcfb4433d131 100644 (file)
@@ -51,20 +51,15 @@ class Cache extends \Friendica\BaseObject
        /**
         * @brief Returns all the cache keys sorted alphabetically
         *
+        * @param string $prefix Prefix of the keys (optional)
+        *
         * @return array|null Null if the driver doesn't support this feature
         */
-       public static function getAllKeys()
+       public static function getAllKeys($prefix = null)
        {
                $time = microtime(true);
 
-               $return = self::getDriver()->getAllKeys();
-
-               // Keys are prefixed with the node hostname, let's remove it
-               array_walk($return, function (&$value) {
-                       $value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
-               });
-
-               sort($return);
+               $return = self::getDriver()->getAllKeys($prefix);
 
                self::getApp()->save_timestamp($time, 'cache');
 
index 15b822dc3b519f8e0fac9412429991a1f06384f7..e694b9c31405ba8b7ee93837c1664c0de0092374 100644 (file)
@@ -17,8 +17,55 @@ abstract class AbstractCacheDriver extends BaseObject
         * @param string $key   The original key
         * @return string               The cache key used for the cache
         */
-       protected function getCacheKey($key) {
+       protected function getCacheKey($key)
+       {
                // We fetch with the hostname as key to avoid problems with other applications
                return self::getApp()->get_hostname() . ":" . $key;
        }
+
+       /**
+        * @param array $keys   A list of cached keys
+        * @return array        A list of original keys
+        */
+       protected function getOriginalKeys($keys)
+       {
+               if (empty($keys)) {
+                       return [];
+               } else {
+                       // Keys are prefixed with the node hostname, let's remove it
+                       array_walk($keys, function (&$value) {
+                               $value = preg_replace('/^' . self::getApp()->get_hostname() . ':/', '', $value);
+                       });
+
+                       sort($keys);
+
+                       return $keys;
+               }
+       }
+
+       /**
+        * Filters a list for a given prefix
+        *
+        * @param array $list the list
+        * @param string|null $prefix the prefix
+        *
+        * @return array the filtered list
+        */
+       protected function filterPrefix($list, $prefix = null)
+       {
+               if (empty($prefix)) {
+                       return array_keys($list);
+               } else {
+                       $result = [];
+
+                       foreach (array_keys($list) as $key) {
+                               if (strpos($key, $prefix) === 0) {
+                                       array_push($result, $key);
+                               }
+                       }
+
+                       return $result;
+               }
+
+       }
 }
index 47c9c166808b86b8b53b4bac601223ac2a3c00e3..0d314fadb7d6580bf7f0b487b01c269f43ef900f 100644 (file)
@@ -22,9 +22,9 @@ class ArrayCache extends AbstractCacheDriver implements IMemoryCacheDriver
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               return array_keys($this->cachedData);
+               return $this->filterPrefix($this->cachedData, $prefix);
        }
 
        /**
index 74dfe3991e1ca4beeb818db1bf23f885a5903cb7..9966457467cfbb6689fbb61cd3fd8a04036b5b2b 100644 (file)
@@ -16,11 +16,23 @@ class DatabaseCacheDriver extends AbstractCacheDriver implements ICacheDriver
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               $stmt = DBA::select('cache', ['k'], ['`expires` >= ?', DateTimeFormat::utcNow()]);
+               if (empty($prefix)) {
+                       $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+               } else {
+                       $where = ['`expires` >= ? AND k LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+               }
+
+               $stmt = DBA::select('cache', ['k'], $where);
+
+               $list = [];
+               while ($key = DBA::fetch($stmt)) {
+                       array_push($list, $key['k']);
+               }
+               DBA::close($stmt);
 
-               return DBA::toArray($stmt);
+               return $list;
        }
 
        /**
index b77aa03c162de44abea89ac60415e735cc03d5e0..0a206559ccbf908e4724600075445eb7df7fa143 100644 (file)
@@ -14,9 +14,11 @@ interface ICacheDriver
        /**
         * Lists all cache keys
         *
+        * @param string prefix optional a prefix to search
+        *
         * @return array|null Null if it isn't supported by the cache driver
         */
-       public function getAllKeys();
+       public function getAllKeys($prefix = null);
 
        /**
         * Fetches cached data according to the key
index 207225b1a269eed59913d633de7c63bdbb2a61fe..f31e21d14e1a9a239f8aabb30a38ee2cb0d042de 100644 (file)
@@ -43,7 +43,7 @@ class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDri
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
                $list = [];
                $allSlabs = $this->memcache->getExtendedStats('slabs');
@@ -59,7 +59,9 @@ class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDri
                        }
                }
 
-               return $list;
+               $list = $this->getOriginalKeys($list);
+
+               return $this->filterPrefix($list, $prefix);
        }
 
        /**
index c1d08f33212855d3ef9b8f16df081fa636fbd84d..82df98f13bb5c6c584fbb348caa01516aab209ee 100644 (file)
@@ -5,6 +5,7 @@ namespace Friendica\Core\Cache;
 use Friendica\Core\Cache;
 
 use Exception;
+use Friendica\Network\HTTPException\InternalServerErrorException;
 use Memcached;
 
 /**
@@ -40,6 +41,9 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
 
                $this->memcached = new Memcached();
 
+
+               $this->memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, false);
+
                array_walk($memcached_hosts, function (&$value) {
                        if (is_string($value)) {
                                $value = array_map('trim', explode(',', $value));
@@ -56,9 +60,15 @@ class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDr
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               return $this->memcached->getAllKeys();
+               // Doesn't work because of https://github.com/php-memcached-dev/php-memcached/issues/367
+               // returns everytime an empty array
+               throw new InternalServerErrorException('getAllKeys for Memcached not supported yet');
+
+               $list = $this->getOriginalKeys($this->memcached->getAllKeys());
+
+               return $this->filterPrefix($list, $prefix);
        }
 
        /**
index f9d00fde21fb4c3366ec8878f5e3f8dcdf4a69df..fcbfab548a6b2bfba0e74e150a7d7b5f505dd9e1 100644 (file)
@@ -41,9 +41,17 @@ class RedisCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys()
+       public function getAllKeys($prefix = null)
        {
-               return null;
+               if (empty($prefix)) {
+                       $search = '*';
+               } else {
+                       $search = $prefix . '*';
+               }
+
+               $list = $this->redis->keys($this->getCacheKey($search));
+
+               return $this->getOriginalKeys($list);
        }
 
        /**
index 2d3508894a4007b91a1de13c44d8a5cb434d18b9..0dfef43f35b4bbe64fe167de9f91fb1b1200538a 100644 (file)
@@ -105,7 +105,7 @@ HELP;
        private function executeList()
        {
                $prefix = $this->getArgument(1);
-               $keys = Core\Cache::getAllKeys();
+               $keys = Core\Cache::getAllKeys($prefix);
 
                if (empty($prefix)) {
                        $this->out('Listing all cache keys:');
index 0cad6e9c7f5ddd5a9464cd6f4bbab170b078fb40..6863d149ffbf49bd53435a3fd2f583cfc25843f0 100644 (file)
@@ -7,11 +7,6 @@ use Friendica\Core\Cache\ArrayCache;
 
 class ArrayCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = new ArrayCache();
index 5c56c2072f4f13add69b2552cc03531fedadab7f..86bf5e7f01fa2a1e115db8aaee1aa9a15dba6dc4 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Friendica\Test\src\Core\Cache;
 
+use Friendica\Core\Cache\MemcachedCacheDriver;
 use Friendica\Core\Config;
 use Friendica\Test\DatabaseTest;
 use Friendica\Util\DateTimeFormat;
@@ -13,6 +14,12 @@ abstract class CacheTest extends DatabaseTest
         */
        protected $instance;
 
+       /**
+        * @var \Friendica\Core\Cache\IMemoryCacheDriver
+        */
+       protected $cache;
+
+
        abstract protected function getInstance();
 
        protected function setUp()
@@ -29,6 +36,8 @@ abstract class CacheTest extends DatabaseTest
                Config::set('system', 'throttle_limit_week', 100);
                Config::set('system', 'throttle_limit_month', 100);
                Config::set('system', 'theme', 'system_theme');
+
+               $this->instance->clear(false);
        }
 
        /**
@@ -177,4 +186,27 @@ abstract class CacheTest extends DatabaseTest
                $received = $this->instance->get('objVal');
                $this->assertEquals($value, $received, 'Value type changed from ' . gettype($value) . ' to ' . gettype($received));
        }
+
+       /**
+        * @small
+        */
+       public function testGetAllKeys() {
+               if ($this->cache instanceof MemcachedCacheDriver) {
+                       $this->markTestSkipped('Memcached doesn\'t support getAllKeys anymore');
+               }
+
+               $this->assertTrue($this->instance->set('value1', 'test'));
+               $this->assertTrue($this->instance->set('value2', 'test'));
+               $this->assertTrue($this->instance->set('test_value3', 'test'));
+
+               $list = $this->instance->getAllKeys();
+
+               $this->assertContains('value1', $list);
+               $this->assertContains('value2', $list);
+               $this->assertContains('test_value3', $list);
+
+               $list = $this->instance->getAllKeys('test');
+
+               $this->assertContains('test_value3', $list);
+       }
 }
index 5df00fc913581a36d0afffa51f38ecf81424a71b..3cc4a72ed1d6441f6e2e2992401677041c20561e 100644 (file)
@@ -6,11 +6,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
 
 class DatabaseCacheDriverTest extends CacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('database');
index 62f7440033f1db0153133ac5c676eeba88ea110a..db85723af16e41cc967e164c79fc878d3f4a5674 100644 (file)
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class MemcacheCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('memcache');
index 5a07814a383760618ff4ddf9f6e316288119be30..fba5c4a958c4347053305c948b0b40a03db271ff 100644 (file)
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class MemcachedCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('memcached');
index 460c1184ba47b5d2c684c8996b9424c43edd69de..0ee73945b9620ac68b3bdd16f201dce67080624d 100644 (file)
@@ -11,11 +11,6 @@ use Friendica\Core\Cache\CacheDriverFactory;
  */
 class RedisCacheDriverTest extends MemoryCacheTest
 {
-       /**
-        * @var \Friendica\Core\Cache\IMemoryCacheDriver
-        */
-       private $cache;
-
        protected function getInstance()
        {
                $this->cache = CacheDriverFactory::create('redis');