-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
Hi,
we're experiencing issues with warming up twig caches, which require the csrf token storage, which requires a doctrine proxy.
Real life scenario: implementing a memcached version of the TokenStorageInterface and using an entity to determine if the experimentation for it is enabled or not
Reproduction case:
https://github.com/InterNations/cachewarmupbug
A patch to the standard 2.8.4 edition: https://github.com/InterNations/cachewarmupbug/commit/eac6d0d5a2663b60e68577d6a934388cb28466d6
php app/console cache:warmup --no-debug -v
// Warming up the cache for the dev environment with debug false
PHP Warning: require(app/cache/dev/doctrine/orm/Proxies/__CG__AppBundleEntityTest.php): failed to open stream: No such file or directory in vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 209
Warning: require(app/cache/dev/doctrine/orm/Proxies/__CG__AppBundleEntityTest.php): failed to open stream: No such file or directory in vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 209
PHP Fatal error: require(): Failed opening required 'app/cache/dev/doctrine/orm/Proxies/__CG__AppBundleEntityTest.php' (include_path='.:') in vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 209
Fatal error: require(): Failed opening required 'app/cache/dev/doctrine/orm/Proxies/__CG__AppBundleEntityTest.php' (include_path='.:') in vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 209
# config.yml
doctrine:
orm:
auto_generate_proxy_classes: false# services.xml
<service id="security.csrf.token_storage" class="AppBundle\Security\Csrf\TokenStorage\DatabaseTokenStorage">
<argument type="service" id="doctrine.orm.entity_manager" />
</service># DatabaseTokenStorage
class DatabaseTokenStorage implements TokenStorageInterface
{
public function __construct(EntityManagerInterface $em)
{
$proxy = $em->getReference(Test::class, 123);
}The call chain is:
TemplateCacheWarmer -> getTwigService -> getCsrfTokenManager -> getDatabaseTokenStorage -> getEntityManager -> getEntityRepository -> Proxy of Test::class (which is not generated yet)
#0 src/AppBundle/Security/Csrf/TokenStorage/DatabaseTokenStorage.php(12): Doctrine\ORM\EntityManager->getReference('AppBundle\\Entit...', 123)
#1 app/cache/dev/appDevProjectContainer.php(1846): AppBundle\Security\Csrf\TokenStorage\DatabaseTokenStorage->__construct(Object(Doctrine\ORM\EntityManager))
#2 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(316): appDevProjectContainer->getSecurity_Csrf_TokenStorageService()
#3 app/cache/dev/appDevProjectContainer.php(1833): Symfony\Component\DependencyInjection\Container->get('security.csrf.t...')
#4 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(316): appDevProjectContainer->getSecurity_Csrf_TokenManagerService()
#5 app/cache/dev/appDevProjectContainer.php(2868): Symfony\Component\DependencyInjection\Container->get('security.csrf.t...', 2)
#6 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(316): appDevProjectContainer->getTwigService()
#7 app/cache/dev/appDevProjectContainer.php(337): Symfony\Component\DependencyInjection\Container->get('twig')
#8 vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php(316): appDevProjectContainer->getCacheWarmerService()
#9 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php(62): Symfony\Component\DependencyInjection\Container->get('cache_warmer')
#10 vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(259): Symfony\Bundle\FrameworkBundle\Command\CacheWarmupCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(860): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(192): Symfony\Component\Console\Application->doRunCommand(Object(Symfony\Bundle\FrameworkBundle\Command\CacheWarmupCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(92): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(123): Symfony\Bundle\FrameworkBundle\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 app/console(29): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput))
#16 {main}
The cache warmers in the dumped container:
protected function getCacheWarmerService()
{
$a = $this->get('kernel');
$b = $this->get('templating.filename_parser');
$c = new \Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinder($a, $b, ($this->targetDirs[2].'/Resources'));
return $this->services['cache_warmer'] = new \Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate(array(
0 => new \Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplatePathsCacheWarmer($c, $this->get('templating.locator')),
1 => $this->get('kernel.class_cache.cache_warmer'),
2 => new \Symfony\Bundle\FrameworkBundle\CacheWarmer\TranslationsCacheWarmer($this->get('translator')),
3 => new \Symfony\Bundle\FrameworkBundle\CacheWarmer\RouterCacheWarmer($this->get('router')),
4 => new \Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer($this, $c, array()),
5 => new \Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer($this->get('twig'), new \Symfony\Bundle\TwigBundle\TemplateIterator($a, $this->targetDirs[2], array())),
6 => new \Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer($this->get('doctrine'))));
}There is a way to circumvent the issue by making the DatabaseTokenStorage service lazy, but my expectation is that Doctrine should be fully available to use once the container is built.