8000 [FrameworkBundle] integrate the Cache component by nicolas-grekas · Pull Request #18371 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[FrameworkBundle] integrate the Cache component #18371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 7, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[FrameworkBundle] use abstract cache.pool decoration and aliases
  • Loading branch information
nicolas-grekas committed Apr 4, 2016
commit 4740c5ccfb4f3264e974b166f0b02e6402317056
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfon 8000 y\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;

/**
* @author Nicolas Grekas <p@tchwork.com>
Expand All @@ -25,36 +26,37 @@ class CachePoolPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
$attributes = array(
'provider_service',
'namespace',
'default_lifetime',
'directory',
);
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $tags) {
$pool = $container->getDefinition($id);
$adapter = $pool = $container->getDefinition($id);
$tags[0] += array('namespace' => $this->getNamespace($id));

if (!$pool instanceof DefinitionDecorator) {
throw new \InvalidArgumentException(sprintf('Services tagged with "cache.pool" must have a parent service but "%s" has none.', $id));
while ($adapter instanceof DefinitionDecorator) {
$adapter = $container->findDefinition($adapter->getParent());
if ($t = $adapter->getTag('cache.pool')) {
$tags[0] += $t[0];
}
}

$adapter = $pool;

do {
$adapterId = $adapter->getParent();
$adapter = $container->getDefinition($adapterId);
} while ($adapter instanceof DefinitionDecorator && !$adapter->hasTag('cache.adapter'));

if (!$adapter->hasTag('cache.adapter')) {
throw new \InvalidArgumentException(sprintf('Services tagged with "cache.pool" must have a parent service tagged with "cache.adapter" but "%s" has none.', $id));
if ($pool->isAbstract()) {
continue;
}

$tags = $adapter->getTag('cache.adapter');

if (!isset($tags[0]['namespace_arg_index'])) {
throw new \InvalidArgumentException(sprintf('Invalid "cache.adapter" tag for service "%s": attribute "namespace_arg_index" is missing.', $adapterId));
if (isset($tags[0]['provider_service']) && is_string($tags[0]['provider_service'])) {
$tags[0]['provider_service'] = new Reference($tags[0]['provider_service']);
}

if (!$adapter->isAbstract()) {
throw new \InvalidArgumentException(sprintf('Services tagged as "cache.adapter" must be abstract: "%s" is not.', $adapterId));
$i = 0;
foreach ($attributes as $attr) {
if (isset($tags[0][$attr])) {
$pool->replaceArgument($i++, $tags[0][$attr]);
unset($tags[0][$attr]);
}
}

if (0 <= $namespaceArgIndex = $tags[0]['namespace_arg_index']) {
$pool->replaceArgument($namespaceArgIndex, $this->getNamespace($id));
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]))));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,13 +561,13 @@ private function addCacheSection(ArrayNodeDefinition $rootNode)
->useAttributeAsKey('name')
->prototype('array')
->children()
->enumNode('type')
->info('The cache pool type (one of "apcu", "doctrine", "psr6" or "filesystem")')
->isRequired()
->values(array('apcu', 'doctrine', 'psr6', 'filesystem'))
->scalarNode('adapter_service')
->info('The cache pool service to use as template definition.')
->defaultValue('cache.adapter.default')
->end()
->integerNode('default_lifetime')->defaultValue(0)->end()
->scalarNode('cache_provider_service')->defaultNull()->end()
->booleanNode('public')->defaultFalse()->end()
->integerNode('default_lifetime')->defaultNull()->end()
->scalarNode('provider_service')->defaultNull()->end()
->scalarNode('directory')->defaultNull()->end()
->end()
->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1023,20 +1023,15 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
if (!empty($config['pools'])) {
$loader->load('cache_adapters.xml');
$loader->load('cache_pools.xml');
}

foreach ($config['pools'] as $name => $poolConfig) {
$poolDefinition = new DefinitionDecorator('cache.adapter.'.$poolConfig['type']);
$poolDefinition->replaceArgument(1, $poolConfig['default_lifetime']);
$poolDefinition = new DefinitionDecorator($poolConfig['adapter_service']);
$poolDefinition->setPublic($poolConfig['public']);
unset($poolConfig['adapter_service'], $poolConfig['public']);

if ('doctrine' === $poolConfig['type'] || 'psr6' === $poolConfig['type']) {
$poolDefinition->replaceArgument(0, new Reference($poolConfig['cache_provider_service']));
} elseif ('filesystem' === $poolConfig['type'] && isset($poolConfig['directory'][0])) {
$poolDefinition->replaceArgument(0, $poolConfig['directory']);
}

$poolDefinition->addTag('cache.pool');
$poolDefinition->addTag('cache.pool', $poolConfig);
$container->setDefinition('cache.pool.'.$name, $poolDefinition);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,33 @@

<services>

<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.adapter" namespace-arg-index="0" />
<tag name="cache.pool" />
<argument /> <!-- namespace -->
<argument /> <!-- default lifetime -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other services namespace is third argument but here is first. Maybe better change constructor signature for better consistency?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But default lifetime is always second...

</service>

<service id="cache.adapter.doctrine" class="Symfony\Component\Cache\Adapter\DoctrineAdapter" abstract="true">
<tag name="cache.adapter" namespace-arg-index="2" />
<argument /> <!-- doctrine provider service -->
<argument /> <!-- default lifetime -->
<tag name="cache.pool" />
<argument /> <!-- Doctrine provider service -->
<argument /> <!-- namespace -->
<argument /> <!-- default lifetime -->
</service>

<service id="cache.adapter.psr6" class="Symfony\Component\Cache\Adapter\ProxyAdapter" abstract="true">
<tag name="cache.adapter" namespace-arg-index="2" />
<tag name="cache.pool" />
<argument /> <!-- PSR-6 provider service -->
<argument /> <!-- default lifetime -->
<argument /> <!-- namespace -->
<argument /> <!-- default lifetime -->
</service>

<service id="cache.adapter.filesystem" class="Symfony\Component\Cache\Adapter\FilesystemAdapter" abstract="true">
<tag name="cache.adapter" namespace-arg-index="2" />
<argument>%kernel.cache_dir%</argument>
<argument /> <!-- default lifetime -->
<tag name="cache.pool" />
<argument /> <!-- namespace -->
<argument /> <!-- default lifetime -->
<argument>%kernel.cache_dir%</argument>
</service>

</services>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,10 @@

<xsd:complexType name="cache_pool">
<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="type" type="xsd:string" use="required" />
<xsd:attribute name="adapter-service" type="xsd:string" />
<xsd:attribute name="public" type="xsd:boolean" />
<xsd:attribute name="default-lifetime" type="xsd:integer" />
<xsd:attribute name="cache-provider-service" type="xsd:string" />
<xsd:attribute name="provider-service" type="xsd:string" />
<xsd:attribute name="directory" type="xsd:string" />
</xsd:complexType>
</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;

class CachePoolPassTest extends \PHPUnit_Framework_TestCase
{
Expand All @@ -30,9 +31,10 @@ public function testNamespaceArgumentIsReplaced()
$container = new ContainerBuilder();
$adapter = new Definition();
$adapter->setAbstract(true);
$adapter->addTag('cache.adapter', array('namespace_arg_index' => 0));
$adapter->addTag('cache.pool');
$container->setDefinition('app.cache_adapter', $adapter);
$cachePool = new DefinitionDecorator('app.cache_adapter');
$container->setAlias('app.cache_adapter_alias', 'app.cache_adapter');
$cachePool = new DefinitionDecorator('app.cache_adapter_alias');
$cachePool->addArgument(null);
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);
Expand All @@ -42,65 +44,40 @@ public function testNamespaceArgumentIsReplaced()
$this->assertSame('yRnzIIVLvL', $cachePool->getArgument(0));
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Services tagged with "cache.pool" must have a parent service but "app.cache_pool" has none.
*/
public function testThrowsExceptionWhenCachePoolHasNoParentDefinition()
public function testArgsAreReplaced()
{
$container = new ContainerBuilder();
$cachePool = new Definition();
$cachePool->addTag('cache.pool');
$cachePool->addTag('cache.pool', array(
'provider_service' => 'foobar',
'default_lifetime' => 3,
));
$cachePool->addArgument(null);
$cachePool->addArgument(null);
$cachePool->addArgument(null);
$container->setDefinition('app.cache_pool', $cachePool);

$this->cachePoolPass->process($container);
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Services tagged with "cache.pool" must have a parent service tagged with "cache.adapter" but "app.cache_pool" has none.
*/
public function testThrowsExceptionWhenCachePoolIsNotBasedOnAdapter()
{
$container = new ContainerBuilder();
$container->register('app.cache_adapter');
$cachePool = new DefinitionDecorator('app.cache_adapter');
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);

$this->cachePoolPass->process($container);
$this->assertInstanceOf(Reference::class, $cachePool->getArgument(0));
$this->assertSame('foobar', (string) $cachePool->getArgument(0));
$this->assertSame('yRnzIIVLvL', $cachePool->getArgument(1));
$this->assertSame(3, $cachePool->getArgument(2));
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Invalid "cache.adapter" tag for service "app.cache_adapter": attribute "namespace_arg_index" is missing.
* @expectedExceptionMessage Invalid "cache.pool" tag for service "app.cache_pool": accepted attributes are
*/
public function testThrowsExceptionWhenCacheAdapterDefinesNoNamespaceArgument()
public function testThrowsExceptionWhenCachePoolTagHasUnknownAttributes()
{
$container = new ContainerBuilder();
$adapter = new Definition();
$adapter->setAbstract(true);
$adapter->addTag('cache.adapter');
$adapter->addTag('cache.pool');
$container->setDefinition('app.cache_adapter', $adapter);
$cachePool = new DefinitionDecorator('app.cache_adapter');
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);

$this->cachePoolPass->process($container);
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Services tagged as "cache.adapter" must be abstract: "app.cache_adapter" is not.
*/
public function testThrowsExceptionWhenCacheAdapterIsNotAbstract()
{
$container = new ContainerBuilder();
$adapter = new Definition();
$adapter->addTag('cache.adapter', array('namespace_arg_index' => 0));
$container->setDefinition('app.cache_adapter', $adapter);
$cachePool = new DefinitionDecorator('app.cache_adapter');
$cachePool->addTag('cache.pool');
$cachePool->addTag('cache.pool', array('foobar' => 123));
$container->setDefinition('app.cache_pool', $cachePool);

$this->cachePoolPass->process($container);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@
'cache' => array(
'pools' => array(
'foo' => array(
'type' => 'apcu',
'adapter_service' => 'cache.adapter.apcu',
'default_lifetime' => 30,
),
'bar' => array(
'type' => 'doctrine',
'adapter_service' => 'cache.adapter.doctrine',
'default_lifetime' => 5,
'cache_provider_service' => 'app.doctrine_cache_provider',
'provider_service' => 'app.doctrine_cache_provider',
),
'baz' => array(
'type' => 'filesystem',
'adapter_service' => 'cache.adapter.filesystem',
'default_lifetime' => 7,
'directory' => 'app/cache/psr',
),
'foobar' => array(
'type' => 'psr6',
'adapter_service' => 'cache.adapter.psr6',
'default_lifetime' => 10,
'cache_provider_service' => 'app.cache_pool',
'provider_service' => 'app.cache_pool',
),
'def' => array(
'default_lifetime' => 11,
),
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

<framework:config>
<framework:cache>
<framework:pool name="foo" type="apcu" default-lifetime="30" />
<framework:pool name="bar" type="doctrine" default-lifetime="5" cache-provider-service="app.doctrine_cache_provider" />
<framework:pool name="baz" type="filesystem" default-lifetime="7" directory="app/cache/psr" />
<framework:pool name="foobar" type="psr6" default-lifetime="10" cache-provider-service="app.cache_pool" />
<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="def" default-lifetime="11" />
</framework:cache>
</framework:config>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ framework:
cache:
pools:
foo:
type: apcu
adapter_service: cache.adapter.apcu
default_lifetime: 30
bar:
type: doctrine
adapter_service: cache.adapter.doctrine
default_lifetime: 5
cache_provider_service: app.doctrine_cache_provider
provider_service: app.doctrine_cache_provider
baz:
type: filesystem
adapter_service: cache.adapter.filesystem
default_lifetime: 7
directory: app/cache/psr
foobar:
type: psr6
adapter_service: cache.adapter.psr6
default_lifetime: 10
cache_provider_service: app.cache_pool
provider_service: app.cache_pool
def:
default_lifetime: 11
Loading
0