Kunstmaan / KunstmaanBundlesCMS

An advanced yet user-friendly content management system, based on the full stack Symfony framework combined with a whole host of community bundles. It provides a full featured, multi-language CMS system with an innovative page and form assembling process, versioning, workflow, translation and media managers and much more.
https://kunstmaancms.be
MIT License
402 stars 186 forks source link

[Deployment] cache:warmup in prod env throw doctrine proxy errors. #1067

Closed lroth closed 8 years ago

lroth commented 8 years ago

During the development everything works like a charm.

When I tried to make deploy using capistrano, I find out that the cache:warmup --env=prod is causing the error. It seems like one of the warmers tried to access the doctrine proxies before those are created in the cache directory. Error I get is something like this: Fatal error: require(): Failed opening required '/app/cache/prod/doctrine/orm/Proxies/__CG__KunstmaanNodeBundleEntityNode.php'

When I generate the proxies via cli and then run the warmup in prod env everything is working fine.

What more, the same situation I have on clean install with demosite skeleton. Anyone figure out how to solve it?

jverdeyen commented 8 years ago

I also had this issue a while ago. Resolved it by enabling auto generating proxy classes.

doctrine:
    orm:
        auto_generate_proxy_classes: true

Let me know if this works for you.

lroth commented 8 years ago

@jverdeyen I assume that this will help but your setting side effect is that the proxy files are generated on-the-fly like in dev mode. I still believe that there is a better solution but thanks for your advice.

sandergo90 commented 8 years ago

Hi @lroth

We had this problem also.

Can you check if you have any MenuAdapters or something else that is trying to do a query in the construct method ?

Sander

lroth commented 8 years ago

@sandergo90 I'm not sure which constructor you mention but what I figure out is that the cache file called "appProdProjectContainer.php" contain method called "getCacheWarmerService"

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 => new \Symfony\Bundle\AsseticBundle\CacheWarmer\AssetManagerCacheWarmer($this), 2 => $this->get('kernel.class_cache.cache_warmer'), 3 => new \Symfony\Bundle\FrameworkBundle\CacheWarmer\TranslationsCacheWarmer($this->get('kunstmaan_translator.service.translator.translator')), 4 => new \Symfony\Bundle\FrameworkBundle\CacheWarmer\RouterCacheWarmer($this->get('cmf_routing.router')), 5 => new \Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer($this, $c, array()), 6 => new \Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer($this->get('twig'), new \Symfony\Bundle\TwigBundle\TemplateIterator($a, $this->targetDirs[2], array())), 7 => new \Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer($this->get('doctrine'))));
    }

and it seems like one of the warmers is called before "ProxyCacheWarmer" and tried to access proxies. Hard coded fix: remove everything and just keep the ProxyCacheWarmer there, run cache warmup in prod, get back to this version, run cache warmup again and it works so I assume that one of those services is a source of the problem.

sandergo90 commented 8 years ago

I mean that we had a problem like yours and in our project the problem was that we had defined a MenuAdapter. In the construct method of this menu adapter we did a query on the entitymanager. But at the phase that the caches are being warmed up, doctrine has not yet made the proxy classes for the entities we were trying to query.

Moving our query outside the construct method was the solution.

lroth commented 8 years ago

@sandergo90 I will take a look at your idea, maybe there is some kind of custom service with query in constructor. What surprised me the most is the fact that the 'demosite' from original cms bundle has the same issue out of the box.

mlebkowski commented 8 years ago

TranslationsCacheWarmer would for sure query the db for translations…

lroth commented 8 years ago

Yep, but I couldn't find a workaround to change the warmers order.

mlebkowski commented 8 years ago

@lroth, there is a priority attribute, so I guess you can try to work it out using a CompulerPass, maybe even modify the \Kunstmaan\TranslatorBundle\DependencyInjection\Compiler\KunstmaanTranslatorCompilerPass

piszczek commented 8 years ago

@sandergo90, thanks. Your solution it's working form me.

I haven't had these errors before until I upgraded kunsmtaan cms to 3.5.1 (from 3.4) and symfony to 2.8