]> git.mxchange.org Git - friendica.git/commitdiff
Move Cache to strategies
authorPhilipp <admin@philipp.info>
Sat, 22 Jul 2023 21:57:38 +0000 (23:57 +0200)
committerPhilipp <admin@philipp.info>
Wed, 26 Jul 2023 17:17:43 +0000 (19:17 +0200)
12 files changed:
src/Core/Cache/Factory/Cache.php
src/Core/Cache/Type/APCuCache.php
src/Core/Cache/Type/AbstractCache.php
src/Core/Cache/Type/ArrayCache.php
src/Core/Cache/Type/DatabaseCache.php
src/Core/Cache/Type/MemcacheCache.php
src/Core/Cache/Type/MemcachedCache.php
src/Core/Cache/Type/RedisCache.php
static/dependencies.config.php
static/strategies.config.php
tests/phpunit-addons.xml [new file with mode: 0644]
tests/src/Core/Cache/DatabaseCacheTest.php

index 107c6ab216da82d8f11a963404724d852c741d5f..b6124c156d2cb019d1b8a0f6a89d88add8cfe015 100644 (file)
 
 namespace Friendica\Core\Cache\Factory;
 
-use Friendica\App\BaseURL;
 use Friendica\Core\Cache\Enum;
 use Friendica\Core\Cache\Capability\ICanCache;
 use Friendica\Core\Cache\Exception\CachePersistenceException;
 use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
 use Friendica\Core\Cache\Type;
 use Friendica\Core\Config\Capability\IManageConfigValues;
-use Friendica\Database\Database;
+use Friendica\Core\Hooks\Capabilities\ICanCreateInstances;
 use Friendica\Util\Profiler;
-use Psr\Log\LoggerInterface;
 
 /**
  * Class CacheFactory
@@ -45,39 +43,18 @@ class Cache
         * @var string The default cache if nothing set
         */
        const DEFAULT_TYPE = Enum\Type::DATABASE;
+       /** @var ICanCreateInstances */
+       protected $instanceCreator;
+       /** @var IManageConfigValues */
+       protected $config;
+       /** @var Profiler */
+       protected $profiler;
 
-       /**
-        * @var IManageConfigValues The IConfiguration to read parameters out of the config
-        */
-       private $config;
-
-       /**
-        * @var Database The database connection in case that the cache is used the dba connection
-        */
-       private $dba;
-
-       /**
-        * @var string The hostname, used as Prefix for Caching
-        */
-       private $hostname;
-
-       /**
-        * @var Profiler The optional profiler if the cached should be profiled
-        */
-       private $profiler;
-
-       /**
-        * @var LoggerInterface The Friendica Logger
-        */
-       private $logger;
-
-       public function __construct(BaseURL $baseURL, IManageConfigValues $config, Database $dba, Profiler $profiler, LoggerInterface $logger)
+       public function __construct(ICanCreateInstances $instanceCreator, IManageConfigValues $config, Profiler $profiler)
        {
-               $this->hostname = $baseURL->getHost();
-               $this->config   = $config;
-               $this->dba      = $dba;
-               $this->profiler = $profiler;
-               $this->logger   = $logger;
+               $this->config          = $config;
+               $this->instanceCreator = $instanceCreator;
+               $this->profiler        = $profiler;
        }
 
        /**
@@ -92,7 +69,7 @@ class Cache
         */
        public function createDistributed(string $type = null): ICanCache
        {
-               if ($type === Enum\Type::APCU) {
+               if ($type === Type\APCuCache::$NAME) {
                        throw new InvalidCacheDriverException('apcu doesn\'t support distributed caching.');
                }
 
@@ -117,31 +94,17 @@ class Cache
        /**
         * Creates a new Cache instance
         *
-        * @param string $type The type of cache
+        * @param string $strategy The strategy, which cache instance should be used
         *
         * @return ICanCache
         *
         * @throws InvalidCacheDriverException In case the underlying cache driver isn't valid or not configured properly
         * @throws CachePersistenceException In case the underlying cache has errors during persistence
         */
-       protected function create(string $type): ICanCache
+       protected function create(string $strategy): ICanCache
        {
-               switch ($type) {
-                       case Enum\Type::MEMCACHE:
-                               $cache = new Type\MemcacheCache($this->hostname, $this->config);
-                               break;
-                       case Enum\Type::MEMCACHED:
-                               $cache = new Type\MemcachedCache($this->hostname, $this->config, $this->logger);
-                               break;
-                       case Enum\Type::REDIS:
-                               $cache = new Type\RedisCache($this->hostname, $this->config);
-                               break;
-                       case Enum\Type::APCU:
-                               $cache = new Type\APCuCache($this->hostname);
-                               break;
-                       default:
-                               $cache = new Type\DatabaseCache($this->hostname, $this->dba);
-               }
+               /** @var ICanCache $cache */
+               $cache = $this->instanceCreator->create(ICanCache::class, $strategy);
 
                $profiling = $this->config->get('system', 'profiling', false);
 
index 05eb2fa0742a57a96e4335d568aaa101edb1d419..02b2d0fbdbffe34f7eb5b7d4c66b2771cf7ed170 100644 (file)
@@ -23,7 +23,6 @@ namespace Friendica\Core\Cache\Type;
 
 use Friendica\Core\Cache\Enum\Duration;
 use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
 use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
 
 /**
@@ -31,12 +30,12 @@ use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
  */
 class APCuCache extends AbstractCache implements ICanCacheInMemory
 {
+       public static $NAME = 'apcu';
+
        use CompareSetTrait;
        use CompareDeleteTrait;
 
        /**
-        * @param string $hostname
-        *
         * @throws InvalidCacheDriverException
         */
        public function __construct(string $hostname)
@@ -173,12 +172,4 @@ class APCuCache extends AbstractCache implements ICanCacheInMemory
 
                return true;
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName(): string
-       {
-               return Type::APCU;
-       }
 }
index 5c00542a77dc3142d4898f198cdcb1af2bc3d1fe..36e301ad209d01d6b1494c5225e9331ec3e7bed2 100644 (file)
@@ -28,6 +28,8 @@ use Friendica\Core\Cache\Capability\ICanCache;
  */
 abstract class AbstractCache implements ICanCache
 {
+       public static $NAME = '';
+
        /**
         * @var string The hostname
         */
@@ -105,4 +107,10 @@ abstract class AbstractCache implements ICanCache
                        return $result;
                }
        }
+
+       /** {@inheritDoc} */
+       public function getName(): string
+       {
+               return static::$NAME;
+       }
 }
index 8886a886a7ae59889a9fc985df44749092a2c0f7..ad87eaf23a0354e33619791dda48a105cd938f1c 100644 (file)
@@ -29,6 +29,8 @@ use Friendica\Core\Cache\Enum;
  */
 class ArrayCache extends AbstractCache implements ICanCacheInMemory
 {
+       public static $NAME = 'array';
+
        use CompareDeleteTrait;
 
        /** @var array Array with the cached data */
@@ -108,12 +110,4 @@ class ArrayCache extends AbstractCache implements ICanCacheInMemory
                        return false;
                }
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName(): string
-       {
-               return Enum\Type::ARRAY;
-       }
 }
index fa7968b650b372db62d178f33452d92a73055731..18541e0d2bdcb6a839aeee804cbdd1f1dcb1fa05 100644 (file)
@@ -32,6 +32,8 @@ use Friendica\Util\DateTimeFormat;
  */
 class DatabaseCache extends AbstractCache implements ICanCache
 {
+       public static $NAME = 'database';
+
        /**
         * @var Database
         */
@@ -154,12 +156,4 @@ class DatabaseCache extends AbstractCache implements ICanCache
                        throw new CachePersistenceException('Cannot clear cache', $exception);
                }
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName(): string
-       {
-               return Enum\Type::DATABASE;
-       }
 }
index d19e7deb1d45c329ddc896881ff4e45015be42f6..09394a1dd33e22cb09d8b917171ef56b3904269f 100644 (file)
@@ -23,7 +23,6 @@ namespace Friendica\Core\Cache\Type;
 
 use Friendica\Core\Cache\Enum\Duration;
 use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
 use Friendica\Core\Cache\Exception\CachePersistenceException;
 use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
 use Friendica\Core\Config\Capability\IManageConfigValues;
@@ -34,6 +33,8 @@ use Memcache;
  */
 class MemcacheCache extends AbstractCache implements ICanCacheInMemory
 {
+       static $NAME = 'memcached';
+
        use CompareSetTrait;
        use CompareDeleteTrait;
        use MemcacheCommandTrait;
@@ -169,12 +170,4 @@ class MemcacheCache extends AbstractCache implements ICanCacheInMemory
                $cacheKey = $this->getCacheKey($key);
                return $this->memcache->add($cacheKey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName(): string
-       {
-               return Type::MEMCACHE;
-       }
 }
index 6d994ddf5796a89282259ead164fffa069440461..45a7a0f1c13305e07485428178b1181a8a449475 100644 (file)
@@ -23,7 +23,6 @@ namespace Friendica\Core\Cache\Type;
 
 use Friendica\Core\Cache\Enum\Duration;
 use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
 use Friendica\Core\Cache\Exception\CachePersistenceException;
 use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
 use Friendica\Core\Config\Capability\IManageConfigValues;
@@ -35,6 +34,8 @@ use Psr\Log\LoggerInterface;
  */
 class MemcachedCache extends AbstractCache implements ICanCacheInMemory
 {
+       static $NAME = 'memcached';
+
        use CompareSetTrait;
        use CompareDeleteTrait;
        use MemcacheCommandTrait;
@@ -185,12 +186,4 @@ class MemcachedCache extends AbstractCache implements ICanCacheInMemory
                $cacheKey = $this->getCacheKey($key);
                return $this->memcached->add($cacheKey, $value, $ttl);
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName(): string
-       {
-               return Type::MEMCACHED;
-       }
 }
index b1fb9ba9c3de6f878554bb9b03d6f8b75dc661b8..36c60a12c18eade8a29198bd630cbff877755bcb 100644 (file)
 
 namespace Friendica\Core\Cache\Type;
 
-use Exception;
 use Friendica\Core\Cache\Enum\Duration;
 use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
 use Friendica\Core\Cache\Exception\CachePersistenceException;
 use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
 use Friendica\Core\Config\Capability\IManageConfigValues;
@@ -35,6 +33,8 @@ use Redis;
  */
 class RedisCache extends AbstractCache implements ICanCacheInMemory
 {
+       public static $NAME = 'redis';
+
        /**
         * @var Redis
         */
@@ -59,18 +59,23 @@ class RedisCache extends AbstractCache implements ICanCacheInMemory
                $redis_pw   = $config->get('system', 'redis_password');
                $redis_db   = $config->get('system', 'redis_db', 0);
 
-               if (!empty($redis_port) && !@$this->redis->connect($redis_host, $redis_port)) {
-                       throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
-               } elseif (!@$this->redis->connect($redis_host)) {
-                       throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ' isn\'t available');
-               }
+               try {
 
-               if (!empty($redis_pw) && !$this->redis->auth($redis_pw)) {
-                       throw new CachePersistenceException('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
-               }
+                       if (!empty($redis_port) && !@$this->redis->connect($redis_host, $redis_port)) {
+                               throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
+                       } else if (!@$this->redis->connect($redis_host)) {
+                               throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ' isn\'t available');
+                       }
+
+                       if (!empty($redis_pw) && !$this->redis->auth($redis_pw)) {
+                               throw new CachePersistenceException('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
+                       }
 
-               if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
-                       throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
+                       if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
+                               throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
+                       }
+               } catch (\RedisException $exception) {
+                       throw new CachePersistenceException('Redis connection fails unexpectedly', $exception);
                }
        }
 
@@ -211,12 +216,4 @@ class RedisCache extends AbstractCache implements ICanCacheInMemory
                $this->redis->unwatch();
                return false;
        }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName(): string
-       {
-               return Type::REDIS;
-       }
 }
index 98a9f3077db211bec8140bdd2d155dbeb48138b0..c3f30ad8d3076ce33906b6fad98c75b9de756fba 100644 (file)
@@ -178,6 +178,20 @@ return [
                        $_SERVER,
                ],
        ],
+       '$hostname'                    => [
+               'instanceOf' => App\BaseURL::class,
+               'constructParams' => [
+                       $_SERVER,
+               ],
+               'call' => [
+                       ['getHost', [], Dice::CHAIN_CALL],
+               ],
+       ],
+       Cache\Type\AbstractCache::class => [
+               'constructParams' => [
+                       [Dice::INSTANCE => '$hostname'],
+               ],
+       ],
        App\Page::class => [
                'constructParams' => [
                        [Dice::INSTANCE => '$basepath'],
index bb3598c369b772d05ba9b57d06c6e18b29ab05c2..5d84a7e47fc125313e868eb4a4924aef5179281a 100644 (file)
@@ -19,7 +19,7 @@
  *
  */
 
-use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H;
+use Friendica\Core\Cache;
 use Friendica\Core\Logger\Type;
 use Psr\Log;
 
@@ -29,4 +29,11 @@ return [
                Type\SyslogLogger::class => ['syslog'],
                Type\StreamLogger::class => ['stream'],
        ],
+       Cache\Capability\ICanCache::class => [
+               Cache\Type\APCuCache::class      => ['apcu'],
+               Cache\Type\DatabaseCache::class  => ['database', ''],
+               Cache\Type\MemcacheCache::class  => ['memcache'],
+               Cache\Type\MemcachedCache::class => ['memcached'],
+               Cache\Type\RedisCache::class     => ['redis'],
+       ]
 ];
diff --git a/tests/phpunit-addons.xml b/tests/phpunit-addons.xml
new file mode 100644 (file)
index 0000000..3793249
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<phpunit
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               bootstrap="bootstrap.php"
+               verbose="true"
+               timeoutForSmallTests="900"
+               timeoutForMediumTests="900"
+               timeoutForLargeTests="900"
+               xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
+       <testsuite name="friendica-addons">
+               <directory suffix=".php">../addon/*/tests/</directory>
+       </testsuite>
+       <!-- Filters for Code Coverage -->
+       <coverage>
+               <include>
+                       <directory suffix=".php">../addon/</directory>
+               </include>
+               <exclude>
+                       <directory suffix=".php">../addon/*/tests/</directory>
+                       <directory suffix=".php">../addon/*/view/</directory>
+                       <directory suffix=".php">../addon/*/vendor/</directory>
+               </exclude>
+       </coverage>
+</phpunit>
index 98afa9e2485e7cff92629a141bddbf3806d2dbc4..63cc7e445203b7b3e9088d82e2c8343d816dba2c 100644 (file)
@@ -21,6 +21,7 @@
 
 namespace Friendica\Test\src\Core\Cache;
 
+use Friendica\App\BaseURL;
 use Friendica\Core\Cache;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\CreateDatabaseTrait;