Dropped support for all caches other than APCu and Array

This commit is contained in:
Alejandro Celaya
2019-04-11 22:36:50 +02:00
parent 5c6829fb62
commit 68f38fd9fe
6 changed files with 12 additions and 177 deletions

View File

@@ -5,98 +5,19 @@ namespace Shlinkio\Shlink\Common\Factory;
use Doctrine\Common\Cache;
use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException;
use Memcached;
use Shlinkio\Shlink\Core\Options\AppOptions;
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
use Zend\ServiceManager\Exception\ServiceNotFoundException;
use Zend\ServiceManager\Factory\FactoryInterface;
use function Functional\contains;
use function Shlinkio\Shlink\Common\env;
use function sys_get_temp_dir;
class CacheFactory implements FactoryInterface
{
private const VALID_CACHE_ADAPTERS = [
Cache\ApcuCache::class,
Cache\ArrayCache::class,
Cache\FilesystemCache::class,
Cache\PhpFileCache::class,
Cache\MemcachedCache::class,
];
private const DEFAULT_MEMCACHED_PORT = 11211;
/**
* Create an object
*
* @param ContainerInterface $container
* @param string $requestedName
* @param null|array $options
* @return object
* @throws ServiceNotFoundException if unable to resolve the service.
* @throws ServiceNotCreatedException if an exception is raised when
* creating a service.
* @throws ContainerException if any other error occurs
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
public function __invoke(ContainerInterface $container, $requestedName, array $options = null): Cache\Cache
{
$appOptions = $container->get(AppOptions::class);
$adapter = $this->getAdapter($container);
$adapter = env('APP_ENV', 'pro') === 'pro' ? new Cache\ApcuCache() : new Cache\ArrayCache();
$adapter->setNamespace((string) $appOptions);
return $adapter;
}
private function getAdapter(ContainerInterface $container): Cache\CacheProvider
{
// Try to get the adapter from config
$config = $container->get('config');
if (isset($config['cache']['adapter']) && contains(self::VALID_CACHE_ADAPTERS, $config['cache']['adapter'])) {
return $this->resolveCacheAdapter($config['cache']);
}
// If the adapter has not been set in config, create one based on environment
return env('APP_ENV', 'pro') === 'pro' ? new Cache\ApcuCache() : new Cache\ArrayCache();
}
private function resolveCacheAdapter(array $cacheConfig): Cache\CacheProvider
{
switch ($cacheConfig['adapter']) {
case Cache\ArrayCache::class:
case Cache\ApcuCache::class:
return new $cacheConfig['adapter']();
case Cache\FilesystemCache::class:
case Cache\PhpFileCache::class:
return new $cacheConfig['adapter']($cacheConfig['options']['dir'] ?? sys_get_temp_dir());
case Cache\MemcachedCache::class:
$cache = new Cache\MemcachedCache();
$cache->setMemcached($this->buildMemcached($cacheConfig));
return $cache;
default:
return new Cache\ArrayCache();
}
}
private function buildMemcached(array $cacheConfig): Memcached
{
$memcached = new Memcached();
$servers = $cacheConfig['options']['servers'] ?? [];
foreach ($servers as $server) {
$this->addMemcachedServer($memcached, $server);
}
return $memcached;
}
private function addMemcachedServer(Memcached $memcached, array $server): void
{
if (! isset($server['host'])) {
return;
}
$port = (int) ($server['port'] ?? self::DEFAULT_MEMCACHED_PORT);
$memcached->addServer($server['host'], $port);
}
}

View File

@@ -5,27 +5,26 @@ namespace ShlinkioTest\Shlink\Common\Factory;
use Doctrine\Common\Cache\ApcuCache;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Cache\FilesystemCache;
use Doctrine\Common\Cache\MemcachedCache;
use Doctrine\Common\Cache\RedisCache;
use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Common\Factory\CacheFactory;
use Shlinkio\Shlink\Core\Options\AppOptions;
use Zend\ServiceManager\ServiceManager;
use function count;
use function putenv;
use function realpath;
use function sys_get_temp_dir;
class CacheFactoryTest extends TestCase
{
/** @var CacheFactory */
private $factory;
/** @var ServiceManager */
private $sm;
public function setUp(): void
{
$this->factory = new CacheFactory();
$this->sm = new ServiceManager(['services' => [
AppOptions::class => new AppOptions(),
]]);
}
public static function tearDownAfterClass(): void
@@ -34,76 +33,18 @@ class CacheFactoryTest extends TestCase
}
/** @test */
public function productionReturnsApcAdapter()
public function productionReturnsApcAdapter(): void
{
putenv('APP_ENV=pro');
$instance = $this->factory->__invoke($this->createSM(), '');
$instance = ($this->factory)($this->sm, '');
$this->assertInstanceOf(ApcuCache::class, $instance);
}
/** @test */
public function developmentReturnsArrayAdapter()
public function developmentReturnsArrayAdapter(): void
{
putenv('APP_ENV=dev');
$instance = $this->factory->__invoke($this->createSM(), '');
$instance = ($this->factory)($this->sm, '');
$this->assertInstanceOf(ArrayCache::class, $instance);
}
/** @test */
public function adapterDefinedInConfigIgnoresEnvironment()
{
putenv('APP_ENV=pro');
$instance = $this->factory->__invoke($this->createSM(ArrayCache::class), '');
$this->assertInstanceOf(ArrayCache::class, $instance);
}
/** @test */
public function invalidAdapterDefinedInConfigFallbacksToEnvironment()
{
putenv('APP_ENV=pro');
$instance = $this->factory->__invoke($this->createSM(RedisCache::class), '');
$this->assertInstanceOf(ApcuCache::class, $instance);
}
/** @test */
public function filesystemCacheAdaptersReadDirOption()
{
$dir = realpath(sys_get_temp_dir());
/** @var FilesystemCache $instance */
$instance = $this->factory->__invoke($this->createSM(FilesystemCache::class, ['dir' => $dir]), '');
$this->assertInstanceOf(FilesystemCache::class, $instance);
$this->assertEquals($dir, $instance->getDirectory());
}
/** @test */
public function memcachedCacheAdaptersReadServersOption()
{
$servers = [
[
'host' => '1.2.3.4',
'port' => 123,
],
[
'host' => '4.3.2.1',
'port' => 321,
],
];
/** @var MemcachedCache $instance */
$instance = $this->factory->__invoke($this->createSM(MemcachedCache::class, ['servers' => $servers]), '');
$this->assertInstanceOf(MemcachedCache::class, $instance);
$this->assertEquals(count($servers), count($instance->getMemcached()->getServerList()));
}
private function createSM($cacheAdapter = null, array $options = [])
{
return new ServiceManager(['services' => [
'config' => isset($cacheAdapter) ? [
'cache' => [
'adapter' => $cacheAdapter,
'options' => $options,
],
] : [],
AppOptions::class => new AppOptions(),
]]);
}
}