symfony: [FrameworkBundle] [Cache] cache:clear warms up cache incorrectly
| Q | A |
|---|---|
| Bug report? | yes |
| Feature request? | no |
| BC Break report? | yes |
| RFC? | no |
| Symfony version | >4.0.3 |
After update Symfony to version 4.0.3 (4.0.4 -the same) cache:clear command (with implicit cache warming) warms up cache incorrectly. As i can compare with 4.0.2 cache folder some dependencies is not warmed.
4.0.3
root@bacac0721dd9:/var/www/symfony# bin/console ca:cl -e=prod
root@bacac0721dd9:/var/www/symfony# ls -1 var/cache/prod/
ContainerM4N54hq
annotations.map
srcProdProjectContainer.php
srcProdProjectContainer.php.meta
srcProdProjectContainerUrlGenerator.php
srcProdProjectContainerUrlGenerator.php.meta
srcProdProjectContainerUrlMatcher.php
srcProdProjectContainerUrlMatcher.php.meta
templates.php
4.0.2
root@bacac0721dd9:/var/www/symfony# bin/console ca:cl -e=prod
root@bacac0721dd9:/var/www/symfony# ls -1 var/cache/prod/
ContainerW99Fklq
annotations.map
annotations.php
doctrine
easy_admin
pools
serialization.php
srcProdProjectContainer.php
srcProdProjectContainer.php.meta
srcProdProjectContainerUrlGenerator.php
srcProdProjectContainerUrlGenerator.php.meta
srcProdProjectContainerUrlMatcher.php
srcProdProjectContainerUrlMatcher.php.meta
templates.php
translations
twig
validation.php
For develop env it isn’t critical, but for production it is.
ps As workaround i used bin/console cache:warmup -e=prod after
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 20 (8 by maintainers)
Hmm, looking into this some more, I think I’ve got an idea of what’s going on. The crux of the issue is that the cache warmer is being passed the cache dir (
prod) instead of the warmup dir (pro_), so warmup cache is generated in the wrong directory. However, this only happens when the warmup container dumps with the same content hash as the previously cached container inprod. Because theappProdProjectContainerclasses are generated with the same namespace, e.g.ContainerBnhddds, but rely on their current directory to generate the right target dirs, an instance of the container in theprodfolder is returned which gives akernel.cache_dirvalue mis-match.cache:clearcommand,var/cache/prod/appProdProjectContainer.phpis included inKernel::initializeContainer, which returns a new instance of\ContainerBnhddds\appProdProjectContainer.CacheClearCommand::warmup, which compiles the container as the warmup cache isn’t fresh (var/cache/pro_/appProdProjectContainer.phpdoesn’t yet exist).var/cache/pro_/appProdProjectContainer.phpis required, an instance of the\ContainerBnhddds\appProdProjectContainerclass inprodis returned.prod, but sincepro_is later renamed toprodinCacheClearCommand::execute, any generated files are lost.I hope this makes sense, I’ve been debugging for a good few hours since I noticed that one 3.4 project exhibited this behaviour and another didn’t, which lead me to https://github.com/doctrine/DoctrineBundle/issues/761 and this issue. I’m not sure why only one project always generates a different build ID each time, or if it’sen meant to, but this clash is certainly causing warmup cache to be put in the wrong directory.
it would still be great to reproduce this to at least make the failure not silent.
@blackandred look at my previously comment. In
devenvironment your application work, because indevsymfony can warm up services on the fly. For test please try following command:bin/console cache:clear --env=dev && ls -l var/cache/devIt show you all files in cache. After that open your application (or just dobin/console cache:warmup --env=dev) and compare cache file list with previous one.@lstrojny excuse me, but after #26128 the time is optionally deterministic. For guys who doesn’t care about reproducible builds (time will difference each run) solution will works fine.
bin/console ca:cl -e=prodwill works correct. Guys who care about reproducible builds, have to fix the build time in parameters, so they will have the same container name (unfortunately,bin/console ca:cl -e=prodwill works incorrect, the same as at now 😦 )roughly speaking - yes. I try explain a bit. When
bin/console ca:cl -e=prodstarted, before command executing Symfony create and dump old kernel in/var/cache/prod/srcProdProjectContainer.php, and then load class vianew ContainerA9d1Z7x\srcProdProjectContainerinto PHP memory. After that CacheClearCommand tried to load/var/cache/pro_/srcProdProjectContainer.phpwitch create new instance of/var/cache/pro_/ContainerA9d1Z7x/srcProdProjectContainer.php, but PHP already has \ContainerA9d1Z7x\srcProdProjectContainer (from/var/cache/prodpath) and return it.So, i think, as PHP can not unload classes from memory, we cant resolve this issue without changing class name.
Hi @xabbuh.
I’ve tried to reproduce issue on small example (framework + templating + doctrine). The bug isn’t reproduced. Looks like some another third party bundle in my project failed while warmed and console command just silently stopped. I’m think this behavior was introduced with #25117. While i was trying play with composer dependencies broken lib was updated and fixed, and bug no more reproduced.