diff --git a/src/Console/Cache.php b/src/Console/Cache.php index 5f508da7a8..754b871dbb 100644 --- a/src/Console/Cache.php +++ b/src/Console/Cache.php @@ -5,8 +5,6 @@ namespace Friendica\Console; use Asika\SimpleConsole\CommandArgsException; use Friendica\App; use Friendica\Core\Cache\ICache; -use Friendica\Core\Config\Configuration; -use Friendica\Factory\CacheDriverFactory; use RuntimeException; /** @@ -71,13 +69,12 @@ HELP; return $help; } - public function __construct(App\Mode $appMode, Configuration $config, ICache $cache, array $argv = null) + public function __construct(App\Mode $appMode, ICache $cache, array $argv = null) { parent::__construct($argv); $this->appMode = $appMode; - $this->cache = $cache; - $this->cacheDriverName = $config->get('system', 'cache_driver', CacheDriverFactory::DEFAULT_DRIVER); + $this->cache = $cache; } protected function doExecute() @@ -94,7 +91,7 @@ HELP; } if ($this->getOption('v')) { - $this->out('Cache Driver Name: ' . $this->cacheDriverName); + $this->out('Cache Driver Name: ' . (string)$this->cache); $this->out('Cache Driver Class: ' . get_class($this->cache)); } @@ -127,7 +124,7 @@ HELP; private function executeList() { $prefix = $this->getArgument(1); - $keys = $this->cache->getAllKeys($prefix); + $keys = $this->cache->getAllKeys($prefix); if (empty($prefix)) { $this->out('Listing all cache keys:'); @@ -147,7 +144,7 @@ HELP; private function executeGet() { if (count($this->args) >= 2) { - $key = $this->getArgument(1); + $key = $this->getArgument(1); $value = $this->cache->get($key); $this->out("{$key} => " . var_export($value, true)); @@ -159,8 +156,8 @@ HELP; private function executeSet() { if (count($this->args) >= 3) { - $key = $this->getArgument(1); - $value = $this->getArgument(2); + $key = $this->getArgument(1); + $value = $this->getArgument(2); $duration = intval($this->getArgument(3, ICache::FIVE_MINUTES)); if (is_array($this->cache->get($key))) { diff --git a/src/Core/Cache/APCuCache.php b/src/Core/Cache/APCuCache.php index 350c8fa067..eb879590e7 100644 --- a/src/Core/Cache/APCuCache.php +++ b/src/Core/Cache/APCuCache.php @@ -153,4 +153,9 @@ class APCuCache extends AbstractCache implements IMemoryCache return true; } + + public function __toString() + { + return self::TYPE_APCU; + } } diff --git a/src/Core/Cache/AbstractCache.php b/src/Core/Cache/AbstractCache.php index c60615f089..c1cd9643c0 100644 --- a/src/Core/Cache/AbstractCache.php +++ b/src/Core/Cache/AbstractCache.php @@ -11,6 +11,20 @@ namespace Friendica\Core\Cache; */ abstract class AbstractCache implements ICache { + const TYPE_APCU = 'apcu'; + const TYPE_ARRAY = 'array'; + const TYPE_DATABASE = 'database'; + const TYPE_MEMCACHE = 'memcache'; + const TYPE_MEMCACHED = 'memcached'; + const TYPE_REDIS = 'redis'; + + /** + * Force each Cache implementation to define the ToString method + * + * @return string + */ + abstract function __toString(); + /** * @var string The hostname */ diff --git a/src/Core/Cache/ArrayCache.php b/src/Core/Cache/ArrayCache.php index 76f867f700..451fec363d 100644 --- a/src/Core/Cache/ArrayCache.php +++ b/src/Core/Cache/ArrayCache.php @@ -92,4 +92,9 @@ class ArrayCache extends AbstractCache implements IMemoryCache return false; } } + + public function __toString() + { + return self::TYPE_ARRAY; + } } diff --git a/src/Core/Cache/DatabaseCache.php b/src/Core/Cache/DatabaseCache.php index 0289ada867..42f40ab1ed 100644 --- a/src/Core/Cache/DatabaseCache.php +++ b/src/Core/Cache/DatabaseCache.php @@ -110,4 +110,9 @@ class DatabaseCache extends AbstractCache implements ICache return $this->dba->delete('cache', ['`k` IS NOT NULL ']); } } + + public function __toString() + { + return self::TYPE_DATABASE; + } } diff --git a/src/Core/Cache/MemcacheCache.php b/src/Core/Cache/MemcacheCache.php index b5b835f488..57c1698c9a 100644 --- a/src/Core/Cache/MemcacheCache.php +++ b/src/Core/Cache/MemcacheCache.php @@ -148,4 +148,9 @@ class MemcacheCache extends AbstractCache implements IMemoryCache $cachekey = $this->getCacheKey($key); return $this->memcache->add($cachekey, serialize($value), MEMCACHE_COMPRESSED, $ttl); } + + public function __toString() + { + return self::TYPE_MEMCACHE; + } } diff --git a/src/Core/Cache/MemcachedCache.php b/src/Core/Cache/MemcachedCache.php index f841cae2ce..e4c4ef352a 100644 --- a/src/Core/Cache/MemcachedCache.php +++ b/src/Core/Cache/MemcachedCache.php @@ -151,4 +151,9 @@ class MemcachedCache extends AbstractCache implements IMemoryCache $cachekey = $this->getCacheKey($key); return $this->memcached->add($cachekey, $value, $ttl); } + + public function __toString() + { + return self::TYPE_MEMCACHED; + } } diff --git a/src/Core/Cache/ProfilerCache.php b/src/Core/Cache/ProfilerCache.php index 72d72b2716..67f606958a 100644 --- a/src/Core/Cache/ProfilerCache.php +++ b/src/Core/Cache/ProfilerCache.php @@ -152,4 +152,9 @@ class ProfilerCache implements ICache, IMemoryCache return false; } } + + public function __toString() + { + return (string)$this->cache . ' (with profiler)'; + } } diff --git a/src/Core/Cache/RedisCache.php b/src/Core/Cache/RedisCache.php index 6f3a647c55..40cb56d35c 100644 --- a/src/Core/Cache/RedisCache.php +++ b/src/Core/Cache/RedisCache.php @@ -192,4 +192,9 @@ class RedisCache extends AbstractCache implements IMemoryCache $this->redis->unwatch(); return false; } + + public function __toString() + { + return self::TYPE_REDIS; + } } diff --git a/src/Core/Lock/CacheLockDriver.php b/src/Core/Lock/CacheLock.php similarity index 96% rename from src/Core/Lock/CacheLockDriver.php rename to src/Core/Lock/CacheLock.php index 69db1c27f8..b38c5ed9af 100644 --- a/src/Core/Lock/CacheLockDriver.php +++ b/src/Core/Lock/CacheLock.php @@ -5,7 +5,7 @@ namespace Friendica\Core\Lock; use Friendica\Core\Cache; use Friendica\Core\Cache\IMemoryCache; -class CacheLockDriver extends AbstractLock +class CacheLock extends AbstractLock { /** * @var \Friendica\Core\Cache\ICache; @@ -13,7 +13,7 @@ class CacheLockDriver extends AbstractLock private $cache; /** - * CacheLockDriver constructor. + * CacheLock constructor. * * @param IMemoryCache $cache The CacheDriver for this type of lock */ diff --git a/src/Factory/CacheDriverFactory.php b/src/Factory/CacheFactory.php similarity index 73% rename from src/Factory/CacheDriverFactory.php rename to src/Factory/CacheFactory.php index f604a0507d..afb799e01c 100644 --- a/src/Factory/CacheDriverFactory.php +++ b/src/Factory/CacheFactory.php @@ -11,18 +11,18 @@ use Friendica\Util\Profiler; use Psr\Log\LoggerInterface; /** - * Class CacheDriverFactory + * Class CacheFactory * * @package Friendica\Core\Cache * * A basic class to generate a CacheDriver */ -class CacheDriverFactory +class CacheFactory { /** - * @var string The default driver for caching + * @var string The default cache if nothing set */ - const DEFAULT_DRIVER = 'database'; + const DEFAULT_TYPE = Cache\AbstractCache::TYPE_DATABASE; /** * @var Configuration The configuration to read parameters out of the config @@ -52,33 +52,37 @@ class CacheDriverFactory public function __construct(BaseURL $baseURL, Configuration $config, Database $dba, Profiler $profiler, LoggerInterface $logger) { $this->hostname = $baseURL->getHostname(); - $this->config = $config; - $this->dba = $dba; + $this->config = $config; + $this->dba = $dba; $this->profiler = $profiler; - $this->logger = $logger; + $this->logger = $logger; } /** * This method creates a CacheDriver for the given cache driver name * + * @param string $type The cache type to create (default is per config) + * * @return ICache The instance of the CacheDriver * @throws \Exception The exception if something went wrong during the CacheDriver creation */ - public function create() + public function create(string $type = null) { - $driver = $this->config->get('system', 'cache_driver', self::DEFAULT_DRIVER); + if (empty($type)) { + $type = $this->config->get('system', 'cache_driver', self::DEFAULT_TYPE); + } - switch ($driver) { - case 'memcache': + switch ($type) { + case Cache\AbstractCache::TYPE_MEMCACHE: $cache = new Cache\MemcacheCache($this->hostname, $this->config); break; - case 'memcached': + case Cache\AbstractCache::TYPE_MEMCACHED: $cache = new Cache\MemcachedCache($this->hostname, $this->config, $this->logger); break; - case 'redis': + case Cache\AbstractCache::TYPE_REDIS: $cache = new Cache\RedisCache($this->hostname, $this->config); break; - case 'apcu': + case Cache\AbstractCache::TYPE_APCU: $cache = new Cache\APCuCache($this->hostname); break; default: @@ -89,7 +93,7 @@ class CacheDriverFactory // In case profiling is enabled, wrap the ProfilerCache around the current cache if (isset($profiling) && $profiling !== false) { - return new Cache\ProfilerCache($cache, $this->profiler); + return new Cache\ProfilerCache($cache, $this->profiler); } else { return $cache; } diff --git a/src/Factory/LockDriverFactory.php b/src/Factory/LockFactory.php similarity index 60% rename from src/Factory/LockDriverFactory.php rename to src/Factory/LockFactory.php index b0c87cfcec..c1e76f6dea 100644 --- a/src/Factory/LockDriverFactory.php +++ b/src/Factory/LockFactory.php @@ -2,7 +2,7 @@ namespace Friendica\Factory; -use Friendica\Core\Cache\ICache; +use Friendica\Core\Cache\AbstractCache; use Friendica\Core\Cache\IMemoryCache; use Friendica\Core\Config\Configuration; use Friendica\Core\Lock; @@ -11,13 +11,13 @@ use Friendica\Util\Profiler; use Psr\Log\LoggerInterface; /** - * Class LockDriverFactory + * Class LockFactory * * @package Friendica\Core\Cache * * A basic class to generate a LockDriver */ -class LockDriverFactory +class LockFactory { /** * @var string The default driver for caching @@ -35,9 +35,9 @@ class LockDriverFactory private $dba; /** - * @var ICache The memory cache driver in case we use it + * @var CacheFactory The memory cache driver in case we use it */ - private $cacheDriver; + private $cacheFactory; /** * @var Profiler The optional profiler if the cached should be profiled @@ -49,25 +49,29 @@ class LockDriverFactory */ private $logger; - public function __construct(ICache $cacheDriver, Configuration $config, Database $dba, Profiler $profiler, LoggerInterface $logger) + public function __construct(CacheFactory $cacheFactory, Configuration $config, Database $dba, Profiler $profiler, LoggerInterface $logger) { - $this->cacheDriver = $cacheDriver; - $this->config = $config; - $this->dba = $dba; - $this->logger = $logger; + $this->cacheFactory = $cacheFactory; + $this->config = $config; + $this->dba = $dba; + $this->logger = $logger; } public function create() { - $lock_driver = $this->config->get('system', 'lock_driver', self::DEFAULT_DRIVER); + $lock_type = $this->config->get('system', 'lock_driver', self::DEFAULT_DRIVER); try { - switch ($lock_driver) { - case 'memcache': - case 'memcached': - case 'redis': - if ($this->cacheDriver instanceof IMemoryCache) { - return new Lock\CacheLockDriver($this->cacheDriver); + switch ($lock_type) { + case AbstractCache::TYPE_MEMCACHE: + case AbstractCache::TYPE_MEMCACHED: + case AbstractCache::TYPE_REDIS: + case AbstractCache::TYPE_APCU: + $cache = $this->cacheFactory->create($lock_type); + if ($cache instanceof IMemoryCache) { + return new Lock\CacheLock($cache); + } else { + throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type)); } break; @@ -83,7 +87,7 @@ class LockDriverFactory return self::useAutoDriver(); } } catch (\Exception $exception) { - $this->logger->alert('Driver \'' . $lock_driver . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]); + $this->logger->alert('Driver \'' . $lock_type . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]); return self::useAutoDriver(); } } @@ -100,7 +104,6 @@ class LockDriverFactory */ private function useAutoDriver() { - // 1. Try to use Semaphores for - local - locking if (function_exists('sem_get')) { try { @@ -111,11 +114,12 @@ class LockDriverFactory } // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!) - $cache_driver = $this->config->get('system', 'cache_driver', 'database'); - if ($cache_driver != 'database') { + $cache_type = $this->config->get('system', 'cache_driver', 'database'); + if ($cache_type != AbstractCache::TYPE_DATABASE) { try { - if ($this->cacheDriver instanceof IMemoryCache) { - return new Lock\CacheLockDriver($this->cacheDriver); + $cache = $this->cacheFactory->create($cache_type); + if ($cache instanceof IMemoryCache) { + return new Lock\CacheLock($cache); } } catch (\Exception $exception) { $this->logger->debug('Using Cache driver for locking failed.', ['exception' => $exception]); diff --git a/static/dependencies.config.php b/static/dependencies.config.php index 1399fe7285..1d0908f325 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -119,16 +119,19 @@ return [ ] ], Cache\ICache::class => [ - 'instanceOf' => Factory\CacheDriverFactory::class, + 'instanceOf' => Factory\CacheFactory::class, 'call' => [ ['create', [], Dice::CHAIN_CALL], ], ], Cache\IMemoryCache::class => [ - 'instanceOf' => Cache\ICache::class, + 'instanceOf' => Factory\CacheFactory::class, + 'call' => [ + ['create', [], Dice::CHAIN_CALL], + ], ], ILock::class => [ - 'instanceOf' => Factory\LockDriverFactory::class, + 'instanceOf' => Factory\LockFactory::class, 'call' => [ ['create', [], Dice::CHAIN_CALL], ], diff --git a/tests/functional/DependencyCheckTest.php b/tests/functional/DependencyCheckTest.php index 9fe469d5e8..bc8d256a78 100644 --- a/tests/functional/DependencyCheckTest.php +++ b/tests/functional/DependencyCheckTest.php @@ -4,8 +4,11 @@ namespace functional; use Dice\Dice; use Friendica\App; +use Friendica\Core\Cache\ICache; +use Friendica\Core\Cache\IMemoryCache; use Friendica\Core\Config\Cache\ConfigCache; use Friendica\Core\Config\Configuration; +use Friendica\Core\Lock\ILock; use Friendica\Database\Database; use Friendica\Test\Util\VFSTrait; use Friendica\Util\BasePath; @@ -133,6 +136,31 @@ class dependencyCheck extends TestCase /** @var LoggerInterface $logger */ $logger = $this->dice->create('$devLogger', ['dev']); - self::assertInstanceOf(LoggerInterface::class, $logger); + $this->assertInstanceOf(LoggerInterface::class, $logger); + } + + public function testCache() + { + /** @var ICache $cache */ + $cache = $this->dice->create(ICache::class); + + $this->assertInstanceOf(ICache::class, $cache); + } + + public function testMemoryCache() + { + /** @var IMemoryCache $cache */ + $cache = $this->dice->create(IMemoryCache::class); + + // We need to check "just" ICache, because the default Cache is DB-Cache, which isn't a memorycache + $this->assertInstanceOf(ICache::class, $cache); + } + + public function testLock() + { + /** @var ILock $cache */ + $lock = $this->dice->create(ILock::class); + + $this->assertInstanceOf(ILock::class, $lock); } } diff --git a/tests/src/Core/Lock/APCuCacheLockTest.php b/tests/src/Core/Lock/APCuCacheLockTest.php index c961013254..3fbb3605a1 100644 --- a/tests/src/Core/Lock/APCuCacheLockTest.php +++ b/tests/src/Core/Lock/APCuCacheLockTest.php @@ -3,7 +3,7 @@ namespace Friendica\Test\src\Core\Lock; use Friendica\Core\Cache\APCuCache; -use Friendica\Core\Lock\CacheLockDriver; +use Friendica\Core\Lock\CacheLock; class APCuCacheLockTest extends LockTest { @@ -18,6 +18,6 @@ class APCuCacheLockTest extends LockTest protected function getInstance() { - return new CacheLockDriver(new APCuCache('localhost')); + return new CacheLock(new APCuCache('localhost')); } } diff --git a/tests/src/Core/Lock/ArrayCacheLockTest.php b/tests/src/Core/Lock/ArrayCacheLockTest.php index aa4ca47538..cc35d7f5e6 100644 --- a/tests/src/Core/Lock/ArrayCacheLockTest.php +++ b/tests/src/Core/Lock/ArrayCacheLockTest.php @@ -3,13 +3,13 @@ namespace Friendica\Test\src\Core\Lock; use Friendica\Core\Cache\ArrayCache; -use Friendica\Core\Lock\CacheLockDriver; +use Friendica\Core\Lock\CacheLock; class ArrayCacheLockTest extends LockTest { protected function getInstance() { - return new CacheLockDriver(new ArrayCache('localhost')); + return new CacheLock(new ArrayCache('localhost')); } public function testLockTTL() diff --git a/tests/src/Core/Lock/MemcacheCacheLockTest.php b/tests/src/Core/Lock/MemcacheCacheLockTest.php index b4272b0d25..f550ac51a6 100644 --- a/tests/src/Core/Lock/MemcacheCacheLockTest.php +++ b/tests/src/Core/Lock/MemcacheCacheLockTest.php @@ -5,7 +5,7 @@ namespace Friendica\Test\src\Core\Lock; use Friendica\Core\Cache\MemcacheCache; use Friendica\Core\Config\Configuration; -use Friendica\Core\Lock\CacheLockDriver; +use Friendica\Core\Lock\CacheLock; /** * @requires extension Memcache @@ -25,6 +25,6 @@ class MemcacheCacheLockTest extends LockTest ->with('system', 'memcache_port') ->andReturn(11211); - return new CacheLockDriver(new MemcacheCache('localhost', $configMock)); + return new CacheLock(new MemcacheCache('localhost', $configMock)); } } diff --git a/tests/src/Core/Lock/MemcachedCacheLockTest.php b/tests/src/Core/Lock/MemcachedCacheLockTest.php index ab5d678d68..8b59f91bb7 100644 --- a/tests/src/Core/Lock/MemcachedCacheLockTest.php +++ b/tests/src/Core/Lock/MemcachedCacheLockTest.php @@ -5,7 +5,7 @@ namespace Friendica\Test\src\Core\Lock; use Friendica\Core\Cache\MemcachedCache; use Friendica\Core\Config\Configuration; -use Friendica\Core\Lock\CacheLockDriver; +use Friendica\Core\Lock\CacheLock; use Psr\Log\NullLogger; /** @@ -24,6 +24,6 @@ class MemcachedCacheLockTest extends LockTest $logger = new NullLogger(); - return new CacheLockDriver(new MemcachedCache('localhost', $configMock, $logger)); + return new CacheLock(new MemcachedCache('localhost', $configMock, $logger)); } } diff --git a/tests/src/Core/Lock/RedisCacheLockTest.php b/tests/src/Core/Lock/RedisCacheLockTest.php index dab31f5e3c..0ebc02160e 100644 --- a/tests/src/Core/Lock/RedisCacheLockTest.php +++ b/tests/src/Core/Lock/RedisCacheLockTest.php @@ -5,7 +5,7 @@ namespace Friendica\Test\src\Core\Lock; use Friendica\Core\Cache\RedisCache; use Friendica\Core\Config\Configuration; -use Friendica\Core\Lock\CacheLockDriver; +use Friendica\Core\Lock\CacheLock; /** * @requires extension redis @@ -34,6 +34,6 @@ class RedisCacheLockTest extends LockTest ->with('system', 'redis_password') ->andReturn(null); - return new CacheLockDriver(new RedisCache('localhost', $configMock)); + return new CacheLock(new RedisCache('localhost', $configMock)); } }