Skip to content

Commit

Permalink
bug #20601 [FrameworkBundle] Don't rely on any parent definition for …
Browse files Browse the repository at this point in the history
…"cache.annotations" (nicolas-grekas)

This PR was merged into the 3.2 branch.

Discussion
----------

[FrameworkBundle] Don't rely on any parent definition for "cache.annotations"

| Q             | A
| ------------- | ---
| Branch?       | 3.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Instead of a generic approach that failed in #20537, let's focus on the `cache.annotations` service, which is the one that needs special care because it can be required while the container is being built. See e.g.:
- #20234
- http://stackoverflow.com/questions/39625863/vichuploadbundle-inb-symfony-3-cant-load-cache-annotations-service/40626277
- schmittjoh/JMSDiExtraBundle#262

When the service is required at build time, we can't provide it a logger, because no logger service is ready at that time. Still, that doesn't prevent the service from working. The late `CachePoolClearerPass` wires the logger for later instantiations so that `cache.annotations` has a properly configured logger *for the next requests*.

Commits
-------

f62b820 [FrameworkBundle] Dont rely on any parent definition for "cache.annotations"
  • Loading branch information
fabpot committed Nov 26, 2016
2 parents 942cfc9 + f62b820 commit 24c40e0
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;

use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
Expand Down Expand Up @@ -38,5 +39,22 @@ public function process(ContainerBuilder $container)
}
}
}

if (!$container->has('cache.annotations')) {
return;
}
$factory = array(AbstractAdapter::class, 'createSystemCache');
$annotationsPool = $container->getDefinition('cache.annotations');
if ($factory !== $annotationsPool->getFactory() || 4 !== count($annotationsPool->getArguments())) {
return;
}
if ($container->has('monolog.logger.cache')) {
$annotationsPool->addArgument(new Reference('monolog.logger.cache'));
} elseif ($container->has('cache.system')) {
$systemPool = $container->getDefinition('cache.system');
if ($factory === $systemPool->getFactory() && 5 <= count($systemArgs = $systemPool->getArguments())) {
$annotationsPool->addArgument($systemArgs[4]);
}
}
}
}
Expand Up @@ -1238,6 +1238,7 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
private function registerCacheConfiguration(array $config, ContainerBuilder $container)
{
$version = substr(str_replace('/', '-', base64_encode(hash('sha256', uniqid(mt_rand(), true), true))), 0, 22);
$container->getDefinition('cache.annotations')->replaceArgument(2, $version);
$container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version);
$container->getDefinition('cache.adapter.system')->replaceArgument(2, $version);
$container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']);
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
Expand Up @@ -93,12 +93,12 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new SerializerPass());
$container->addCompilerPass(new PropertyInfoPass());
$container->addCompilerPass(new ControllerArgumentValueResolverPass());
$container->addCompilerPass(new CachePoolPass());
$container->addCompilerPass(new CachePoolPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 32);
$container->addCompilerPass(new ValidateWorkflowsPass());
$container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING);

if ($container->getParameter('kernel.debug')) {
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1);
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
Expand Down
9 changes: 7 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
Expand Up @@ -22,8 +22,13 @@
<tag name="cache.pool" />
</service>

<service id="cache.annotations" parent="cache.system" public="false">
<tag name="cache.pool" />
<service id="cache.annotations" class="Symfony\Component\Cache\Adapter\AdapterInterface" public="false">
<factory class="Symfony\Component\Cache\Adapter\AbstractAdapter" method="createSystemCache" />
<tag name="cache.pool" clearer="cache.default_clearer" />
<argument /> <!-- namespace -->
<argument>0</argument> <!-- default lifetime -->
<argument /> <!-- version -->
<argument>%kernel.cache_dir%/pools</argument>
</service>

<service id="cache.adapter.system" class="Symfony\Component\Cache\Adapter\AdapterInterface" abstract="true">
Expand Down

0 comments on commit 24c40e0

Please sign in to comment.