[FrameworkBundle] Add & use Psr6CacheClearer
This commit is contained in:
parent
4740c5ccfb
commit
714b916d5d
@ -27,36 +27,47 @@ class CachePoolPass implements CompilerPassInterface
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$attributes = array(
|
||||
'provider_service',
|
||||
'provider',
|
||||
'namespace',
|
||||
'default_lifetime',
|
||||
'directory',
|
||||
);
|
||||
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $tags) {
|
||||
$adapter = $pool = $container->getDefinition($id);
|
||||
$tags[0] += array('namespace' => $this->getNamespace($id));
|
||||
|
||||
if ($pool->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($tags[0]['namespace'])) {
|
||||
$tags[0]['namespace'] = $this->getNamespace($id);
|
||||
}
|
||||
while ($adapter instanceof DefinitionDecorator) {
|
||||
$adapter = $container->findDefinition($adapter->getParent());
|
||||
if ($t = $adapter->getTag('cache.pool')) {
|
||||
$tags[0] += $t[0];
|
||||
}
|
||||
}
|
||||
if ($pool->isAbstract()) {
|
||||
continue;
|
||||
if (isset($tags[0]['clearer'])) {
|
||||
$clearer = $container->getDefinition($tags[0]['clearer']);
|
||||
} else {
|
||||
$clearer = null;
|
||||
}
|
||||
if (isset($tags[0]['provider_service']) && is_string($tags[0]['provider_service'])) {
|
||||
$tags[0]['provider_service'] = new Reference($tags[0]['provider_service']);
|
||||
unset($tags[0]['clearer']);
|
||||
|
||||
if (isset($tags[0]['provider']) && is_string($tags[0]['provider'])) {
|
||||
$tags[0]['provider'] = new Reference($tags[0]['provider']);
|
||||
}
|
||||
$i = 0;
|
||||
foreach ($attributes as $attr) {
|
||||
if (isset($tags[0][$attr])) {
|
||||
$pool->replaceArgument($i++, $tags[0][$attr]);
|
||||
unset($tags[0][$attr]);
|
||||
}
|
||||
unset($tags[0][$attr]);
|
||||
}
|
||||
if (!empty($tags[0])) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "provider_service", "namespace", "default_lifetime" and "directory", found "%s".', $id, implode('", "', array_keys($tags[0]))));
|
||||
throw new \InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "provider", "namespace" and "default_lifetime", found "%s".', $id, implode('", "', array_keys($tags[0]))));
|
||||
}
|
||||
|
||||
if (null !== $clearer) {
|
||||
$clearer->addMethodCall('addPool', array(new Reference($id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -561,14 +561,19 @@ class Configuration implements ConfigurationInterface
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->children()
|
||||
->scalarNode('adapter_service')
|
||||
->info('The cache pool service to use as template definition.')
|
||||
->scalarNode('adapter')
|
||||
->info('The cache pool adapter service to use as template definition.')
|
||||
->defaultValue('cache.adapter.default')
|
||||
->end()
|
||||
->booleanNode('public')->defaultFalse()->end()
|
||||
->integerNode('default_lifetime')->defaultNull()->end()
|
||||
->scalarNode('provider_service')->defaultNull()->end()
|
||||
->scalarNode('directory')->defaultNull()->end()
|
||||
->integerNode('default_lifetime')->end()
|
||||
->scalarNode('provider')
|
||||
->info('The service name to use as provider when the specified adapter needs one.')
|
||||
->end()
|
||||
->scalarNode('namespace')
|
||||
->info('The namespace where cached items are stored. Auto-generated by default. Set to false to disable namespacing.')
|
||||
->end()
|
||||
->scalarNode('clearer')->defaultValue('cache.default_pools_clearer')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
|
@ -1027,9 +1027,9 @@ class FrameworkExtension extends Extension
|
||||
}
|
||||
|
||||
foreach ($config['pools'] as $name => $poolConfig) {
|
||||
$poolDefinition = new DefinitionDecorator($poolConfig['adapter_service']);
|
||||
$poolDefinition = new DefinitionDecorator($poolConfig['adapter']);
|
||||
$poolDefinition->setPublic($poolConfig['public']);
|
||||
unset($poolConfig['adapter_service'], $poolConfig['public']);
|
||||
unset($poolConfig['adapter'], $poolConfig['public']);
|
||||
|
||||
$poolDefinition->addTag('cache.pool', $poolConfig);
|
||||
$container->setDefinition('cache.pool.'.$name, $poolDefinition);
|
||||
|
@ -6,33 +6,39 @@
|
||||
|
||||
<services>
|
||||
|
||||
<service id="cache.default_pools_clearer" class="Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer" public="false">
|
||||
<tag name="kernel.cache_clearer" />
|
||||
</service>
|
||||
|
||||
<service id="cache.adapter.default" alias="cache.adapter.filesystem" />
|
||||
|
||||
<service id="cache.adapter.apcu" class="Symfony\Component\Cache\Adapter\ApcuAdapter" abstract="true">
|
||||
<tag name="cache.pool" />
|
||||
<argument /> <!-- namespace -->
|
||||
<argument /> <!-- default lifetime -->
|
||||
</service>
|
||||
|
||||
<service id="cache.adapter.doctrine" class="Symfony\Component\Cache\Adapter\DoctrineAdapter" abstract="true">
|
||||
<tag name="cache.pool" />
|
||||
<argument /> <!-- Doctrine provider service -->
|
||||
<argument /> <!-- namespace -->
|
||||
<argument /> <!-- default lifetime -->
|
||||
</service>
|
||||
|
||||
<service id="cache.adapter.filesystem" class="Symfony\Component\Cache\Adapter\FilesystemAdapter" abstract="true">
|
||||
<argument /> <!-- namespace -->
|
||||
<argument /> <!-- default lifetime -->
|
||||
<argument>%kernel.cache_dir%/pools</argument>
|
||||
</service>
|
||||
|
||||
<service id="cache.adapter.psr6" class="Symfony\Component\Cache\Adapter\ProxyAdapter" abstract="true">
|
||||
<tag name="cache.pool" />
|
||||
<argument /> <!-- PSR-6 provider service -->
|
||||
<argument /> <!-- namespace -->
|
||||
<argument /> <!-- default lifetime -->
|
||||
</service>
|
||||
|
||||
<service id="cache.adapter.filesystem" class="Symfony\Component\Cache\Adapter\FilesystemAdapter" abstract="true">
|
||||
<tag name="cache.pool" />
|
||||
<service id="cache.adapter.redis" class="Symfony\Component\Cache\Adapter\RedisAdapter" abstract="true">
|
||||
<argument /> <!-- Redis connection object -->
|
||||
<argument /> <!-- namespace -->
|
||||
<argument /> <!-- default lifetime -->
|
||||
<argument>%kernel.cache_dir%</argument>
|
||||
</service>
|
||||
|
||||
</services>
|
||||
|
@ -212,10 +212,11 @@
|
||||
|
||||
<xsd:complexType name="cache_pool">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="adapter-service" type="xsd:string" />
|
||||
<xsd:attribute name="adapter" type="xsd:string" />
|
||||
<xsd:attribute name="public" type="xsd:boolean" />
|
||||
<xsd:attribute name="default-lifetime" type="xsd:integer" />
|
||||
<xsd:attribute name="provider-service" type="xsd:string" />
|
||||
<xsd:attribute name="provider" type="xsd:string" />
|
||||
<xsd:attribute name="directory" type="xsd:string" />
|
||||
<xsd:attribute name="clearer" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
|
@ -49,7 +49,7 @@ class CachePoolPassTest extends \PHPUnit_Framework_TestCase
|
||||
$container = new ContainerBuilder();
|
||||
$cachePool = new Definition();
|
||||
$cachePool->addTag('cache.pool', array(
|
||||
'provider_service' => 'foobar',
|
||||
'provider' => 'foobar',
|
||||
'default_lifetime' => 3,
|
||||
));
|
||||
$cachePool->addArgument(null);
|
||||
|
@ -4,23 +4,22 @@ $container->loadFromExtension('framework', array(
|
||||
'cache' => array(
|
||||
'pools' => array(
|
||||
'foo' => array(
|
||||
'adapter_service' => 'cache.adapter.apcu',
|
||||
'adapter' => 'cache.adapter.apcu',
|
||||
'default_lifetime' => 30,
|
||||
),
|
||||
'bar' => array(
|
||||
'adapter_service' => 'cache.adapter.doctrine',
|
||||
'adapter' => 'cache.adapter.doctrine',
|
||||
'default_lifetime' => 5,
|
||||
'provider_service' => 'app.doctrine_cache_provider',
|
||||
'provider' => 'app.doctrine_cache_provider',
|
||||
),
|
||||
'baz' => array(
|
||||
'adapter_service' => 'cache.adapter.filesystem',
|
||||
'adapter' => 'cache.adapter.filesystem',
|
||||
'default_lifetime' => 7,
|
||||
'directory' => 'app/cache/psr',
|
||||
),
|
||||
'foobar' => array(
|
||||
'adapter_service' => 'cache.adapter.psr6',
|
||||
'adapter' => 'cache.adapter.psr6',
|
||||
'default_lifetime' => 10,
|
||||
'provider_service' => 'app.cache_pool',
|
||||
'provider' => 'app.cache_pool',
|
||||
),
|
||||
'def' => array(
|
||||
'default_lifetime' => 11,
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
<framework:config>
|
||||
<framework:cache>
|
||||
<framework:pool name="foo" adapter-service="cache.adapter.apcu" default-lifetime="30" />
|
||||
<framework:pool name="bar" adapter-service="cache.adapter.doctrine" default-lifetime="5" provider-service="app.doctrine_cache_provider" />
|
||||
<framework:pool name="baz" adapter-service="cache.adapter.filesystem" default-lifetime="7" directory="app/cache/psr" />
|
||||
<framework:pool name="foobar" adapter-service="cache.adapter.psr6" default-lifetime="10" provider-service="app.cache_pool" />
|
||||
<framework:pool name="foo" adapter="cache.adapter.apcu" default-lifetime="30" />
|
||||
<framework:pool name="bar" adapter="cache.adapter.doctrine" default-lifetime="5" provider="app.doctrine_cache_provider" />
|
||||
<framework:pool name="baz" adapter="cache.adapter.filesystem" default-lifetime="7" />
|
||||
<framework:pool name="foobar" adapter="cache.adapter.psr6" default-lifetime="10" provider="app.cache_pool" />
|
||||
<framework:pool name="def" default-lifetime="11" />
|
||||
</framework:cache>
|
||||
</framework:config>
|
||||
|
@ -2,19 +2,18 @@ framework:
|
||||
cache:
|
||||
pools:
|
||||
foo:
|
||||
adapter_service: cache.adapter.apcu
|
||||
adapter: cache.adapter.apcu
|
||||
default_lifetime: 30
|
||||
bar:
|
||||
adapter_service: cache.adapter.doctrine
|
||||
adapter: cache.adapter.doctrine
|
||||
default_lifetime: 5
|
||||
provider_service: app.doctrine_cache_provider
|
||||
provider: app.doctrine_cache_provider
|
||||
baz:
|
||||
adapter_service: cache.adapter.filesystem
|
||||
adapter: cache.adapter.filesystem
|
||||
default_lifetime: 7
|
||||
directory: app/cache/psr
|
||||
foobar:
|
||||
adapter_service: cache.adapter.psr6
|
||||
adapter: cache.adapter.psr6
|
||||
default_lifetime: 10
|
||||
provider_service: app.cache_pool
|
||||
provider: app.cache_pool
|
||||
def:
|
||||
default_lifetime: 11
|
||||
|
@ -683,7 +683,6 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
break;
|
||||
}
|
||||
|
||||
$this->assertTrue($adapterDefinition->hasTag('cache.pool'), sprintf('Service definition "%s" is tagged with the "cache.pool" tag.', $adapterId));
|
||||
$this->assertTrue($adapterDefinition->isAbstract(), sprintf('Service definition "%s" is abstract.', $adapterId));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\RedisAdapter;
|
||||
|
||||
class CachePoolsTest extends WebTestCase
|
||||
{
|
||||
public function testCachePools()
|
||||
{
|
||||
$this->doTestCachePools(array(), FilesystemAdapter::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires extension redis
|
||||
*/
|
||||
public function testRedisCachePools()
|
||||
{
|
||||
try {
|
||||
$this->doTestCachePools(array('root_config' => 'redis_config.yml', 'environment' => 'redis_cache'), RedisAdapter::class);
|
||||
} catch (\PHPUnit_Framework_Error_Warning $e) {
|
||||
if (0 !== strpos($e->getMessage(), 'unable to connect to 127.0.0.1')) {
|
||||
throw $e;
|
||||
}
|
||||
$this->markTestSkipped($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function doTestCachePools($options, $adapterClass)
|
||||
{
|
||||
static::bootKernel($options);
|
||||
$container = static::$kernel->getContainer();
|
||||
|
||||
$pool = $container->get('cache.pool.test');
|
||||
$this->assertInstanceOf($adapterClass, $pool);
|
||||
|
||||
$key = 'foobar';
|
||||
$pool->deleteItem($key);
|
||||
$item = $pool->getItem($key);
|
||||
$this->assertFalse($item->isHit());
|
||||
|
||||
$item->set('baz');
|
||||
$pool->save($item);
|
||||
$item = $pool->getItem($key);
|
||||
$this->assertTrue($item->isHit());
|
||||
|
||||
$container->get('cache_clearer')->clear($container->getParameter('kernel.cache_dir'));
|
||||
$item = $pool->getItem($key);
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
protected static function createKernel(array $options = array())
|
||||
{
|
||||
return parent::createKernel(array('test_case' => 'CachePools') + $options);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
|
||||
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||
|
||||
return array(
|
||||
new FrameworkBundle(),
|
||||
new TestBundle(),
|
||||
);
|
@ -0,0 +1,8 @@
|
||||
imports:
|
||||
- { resource: ../config/default.yml }
|
||||
|
||||
framework:
|
||||
cache:
|
||||
pools:
|
||||
test:
|
||||
public: true
|
@ -0,0 +1,22 @@
|
||||
imports:
|
||||
- { resource: ../config/default.yml }
|
||||
|
||||
services:
|
||||
cache.adapter.redis.connection:
|
||||
public: false
|
||||
class: Redis
|
||||
calls:
|
||||
- [connect, [127.0.0.1]]
|
||||
|
||||
cache.adapter.default:
|
||||
abstract: true
|
||||
parent: cache.adapter.redis
|
||||
tags:
|
||||
- name: cache.pool
|
||||
provider: cache.adapter.redis.connection
|
||||
|
||||
framework:
|
||||
cache:
|
||||
pools:
|
||||
test:
|
||||
public: true
|
@ -19,7 +19,7 @@
|
||||
"php": ">=5.5.9",
|
||||
"symfony/asset": "~2.8|~3.0",
|
||||
"symfony/class-loader": "~2.8|~3.0",
|
||||
"symfony/dependency-injection": "~2.8|~3.0",
|
||||
"symfony/dependency-injection": "~3.1",
|
||||
"symfony/config": "~2.8|~3.0",
|
||||
"symfony/event-dispatcher": "~2.8|~3.0",
|
||||
"symfony/http-foundation": "~3.1",
|
||||
@ -38,6 +38,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/browser-kit": "~2.8|~3.0",
|
||||
"symfony/cache": "~3.1",
|
||||
"symfony/console": "~2.8|~3.0",
|
||||
"symfony/css-selector": "~2.8|~3.0",
|
||||
"symfony/dom-crawler": "~2.8|~3.0",
|
||||
|
@ -28,6 +28,9 @@ class FilesystemAdapter extends AbstractAdapter
|
||||
$directory = sys_get_temp_dir().'/symfony-cache';
|
||||
}
|
||||
if (isset($namespace[0])) {
|
||||
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
|
||||
throw new InvalidArgumentException(sprintf('FilesystemAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
|
||||
}
|
||||
$directory .= '/'.$namespace;
|
||||
}
|
||||
if (!file_exists($dir = $directory.'/.')) {
|
||||
|
@ -25,6 +25,6 @@ class FilesystemAdapterTest extends CachePoolTest
|
||||
$this->skippedTests['testDeferredSaveWithoutCommit'] = 'Fails on HHVM';
|
||||
}
|
||||
|
||||
return new FilesystemAdapter(sys_get_temp_dir().DIRECTORY_SEPARATOR.'sf-cache');
|
||||
return new FilesystemAdapter('sf-cache');
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ class PassConfig
|
||||
|
||||
$this->removingPasses = array(
|
||||
new RemovePrivateAliasesPass(),
|
||||
new RemoveAbstractDefinitionsPass(),
|
||||
new ReplaceAliasByActualDefinitionPass(),
|
||||
new RemoveAbstractDefinitionsPass(),
|
||||
new RepeatedPass(array(
|
||||
new AnalyzeServiceReferencesPass(),
|
||||
new InlineServiceDefinitionsPass(),
|
||||
@ -102,8 +102,7 @@ class PassConfig
|
||||
throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
|
||||
}
|
||||
|
||||
$passes = &$this->$property;
|
||||
$passes[] = $pass;
|
||||
$this->{$property}[] = $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
/**
|
||||
* This replaces all DefinitionDecorator instances with their equivalent fully
|
||||
@ -96,11 +97,12 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
*/
|
||||
private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
|
||||
{
|
||||
if (!$container->hasDefinition($parent = $definition->getParent())) {
|
||||
try {
|
||||
$parentDef = $container->findDefinition($parent = $definition->getParent());
|
||||
} catch (ServiceNotFoundException $e) {
|
||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId));
|
||||
}
|
||||
|
||||
$parentDef = $container->getDefinition($parent);
|
||||
if ($parentDef instanceof DefinitionDecorator) {
|
||||
$id = $this->currentId;
|
||||
$this->currentId = $parent;
|
||||
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheClearer;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Psr6CacheClearer implements CacheClearerInterface
|
||||
{
|
||||
private $pools = array();
|
||||
|
||||
public function addPool(CacheItemPoolInterface $pool)
|
||||
{
|
||||
$this->pools[] = $pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear($cacheDir)
|
||||
{
|
||||
foreach ($this->pools as $pool) {
|
||||
$pool->clear();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user