Merge pull request #400 from acelaya/feature/simplify-cache

Dropped support for all caches other than APCu and Array
This commit is contained in:
Alejandro Celaya 2019-04-11 22:56:54 +02:00 committed by GitHub
commit ef32f2c129
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 12 additions and 199 deletions

View file

@ -13,7 +13,6 @@ services:
- postgresql
before_install:
- echo 'extension = memcached.so' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- echo 'extension = apcu.so' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- yes | pecl install swoole
- phpenv config-rm xdebug.ini || return 0

View file

@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
#### Changed
* *Nothing*
* [#56](https://github.com/shlinkio/shlink/issues/56) Simplified supported cache, requiring APCu always.
### Deprecated

View file

@ -1,8 +1,6 @@
FROM php:7.3.1-fpm-alpine3.8
MAINTAINER Alejandro Celaya <alejandro@alejandrocelaya.com>
ENV PREDIS_VERSION 4.2.0
ENV MEMCACHED_VERSION 3.1.3
ENV APCU_VERSION 5.1.16
ENV APCU_BC_VERSION 1.0.4
ENV XDEBUG_VERSION "2.7.0RC1"
@ -31,28 +29,6 @@ RUN docker-php-ext-install gd
RUN apk add --no-cache postgresql-dev
RUN docker-php-ext-install pdo_pgsql
# Install redis extension
ADD https://github.com/phpredis/phpredis/archive/$PREDIS_VERSION.tar.gz /tmp/phpredis.tar.gz
RUN mkdir -p /usr/src/php/ext/redis\
&& tar xf /tmp/phpredis.tar.gz -C /usr/src/php/ext/redis --strip-components=1
# configure and install
RUN docker-php-ext-configure redis\
&& docker-php-ext-install redis
# cleanup
RUN rm /tmp/phpredis.tar.gz
# Install memcached extension
RUN apk add --no-cache --virtual cyrus-sasl-dev
RUN apk add --no-cache --virtual libmemcached-dev
ADD https://github.com/php-memcached-dev/php-memcached/archive/v$MEMCACHED_VERSION.tar.gz /tmp/memcached.tar.gz
RUN mkdir -p /usr/src/php/ext/memcached\
&& tar xf /tmp/memcached.tar.gz -C /usr/src/php/ext/memcached --strip-components=1
# configure and install
RUN docker-php-ext-configure memcached\
&& docker-php-ext-install memcached
# cleanup
RUN rm /tmp/memcached.tar.gz
# Install APCu extension
ADD https://pecl.php.net/get/apcu-$APCU_VERSION.tgz /tmp/apcu.tar.gz
RUN mkdir -p /usr/src/php/ext/apcu\

View file

@ -1,8 +1,6 @@
FROM php:7.3.1-cli-alpine3.8
MAINTAINER Alejandro Celaya <alejandro@alejandrocelaya.com>
ENV PREDIS_VERSION 4.2.0
ENV MEMCACHED_VERSION 3.1.3
ENV APCU_VERSION 5.1.16
ENV APCU_BC_VERSION 1.0.4
ENV INOTIFY_VERSION 2.0.0
@ -31,28 +29,6 @@ RUN docker-php-ext-install gd
RUN apk add --no-cache postgresql-dev
RUN docker-php-ext-install pdo_pgsql
# Install redis extension
ADD https://github.com/phpredis/phpredis/archive/$PREDIS_VERSION.tar.gz /tmp/phpredis.tar.gz
RUN mkdir -p /usr/src/php/ext/redis\
&& tar xf /tmp/phpredis.tar.gz -C /usr/src/php/ext/redis --strip-components=1
# configure and install
RUN docker-php-ext-configure redis\
&& docker-php-ext-install redis
# cleanup
RUN rm /tmp/phpredis.tar.gz
# Install memcached extension
RUN apk add --no-cache --virtual cyrus-sasl-dev
RUN apk add --no-cache --virtual libmemcached-dev
ADD https://github.com/php-memcached-dev/php-memcached/archive/v$MEMCACHED_VERSION.tar.gz /tmp/memcached.tar.gz
RUN mkdir -p /usr/src/php/ext/memcached\
&& tar xf /tmp/memcached.tar.gz -C /usr/src/php/ext/memcached --strip-components=1
# configure and install
RUN docker-php-ext-configure memcached\
&& docker-php-ext-install memcached
# cleanup
RUN rm /tmp/memcached.tar.gz
# Install APCu extension
ADD https://pecl.php.net/get/apcu-$APCU_VERSION.tgz /tmp/apcu.tar.gz
RUN mkdir -p /usr/src/php/ext/apcu\

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(),
]]);
}
}