8000 Compile error after cache clear and warmup · Issue #25654 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
8000

Compile error after cache clear and warmup #25654

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

Closed
coudenysj opened this issue Jan 2, 2018 · 17 comments
Closed

Compile error after cache clear and warmup #25654

coudenysj opened this issue Jan 2, 2018 · 17 comments

Comments

@coudenysj
Copy link
Q A
Bug report? yes
Feature request? no
BC Break report? -
RFC? no
Symfony version 3.4.2

This is related to #24885.

Fatal Compile Error: require(): Failed opening required '/.../cache/prod/Container3no4t0t/getSwiftmailer_EmailSender_ListenerService.php' (include_path='.:/usr/share/php')

I run a couple commands during deployment, clear cache, warm cache, other commands, and always get a Fatal Compile Error after the cache warmup:

php bin/console cache:clear --no-warmup --env=prod
php bin/console cache:warmup --env=prod
php bin/console rabbitmq-supervisor:rebuild -vv --no-interaction --env=prod
@nicolas-grekas
Copy link
Member

Would you be able to try with 3.4@dev? I think this is fixed already.
Otherwise, can you provide a reproducer?

@coudenysj
Copy link
Author

So the problem probably lies in the fact that the supervisor processes still look at the old container folder (in memory problem).

@fancyweb
Copy link
Contributor
fancyweb commented Jan 3, 2018

So I had the same error showing up when deploying on prod since I updated to 3.4. I took the time to investigate this problem and found how to reproduce it.

Use this command on a fresh Symfony standard edition :

<?php

namespace AppBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\Process;

class TempCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('app:temp');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     *
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $process = new Process('php bin/console cache:clear');
        $process->run();

        return 0;
    }
}

Works fine on 3.3, fails on 3.4.

untitled

Also I can confirm you that using the same fix as in #24908 is working here. If you have $this->getApplication()->setDispatcher(new EventDispatcher()); at the beginning of the command, there is no error.

@fancyweb
Copy link
Contributor
fancyweb commented Jan 3, 2018

@nicolas-grekas You were right, I just tested it on 3.4@dev and the error is gone.

@coudenysj IMHO, this issue can be closed.

@coudenysj
Copy link
Author

I'll have a look at 3.4@dev.

Currently having the issue in v3.4.2 (29961b6).

@coudenysj
Copy link
Author

I upgraded (29961b6...1b36d03), but still have the issue. It is probably due to the fact that processes still look at the old container.

I'll look in to it later and reopen this issue if it is a problem in Symfony.

@fancyweb
Copy link
Contributor
fancyweb commented Jan 8, 2018

I still have the problem too after upgrading to 3.4.3. My reproducer works but not my real code.

@AntoineLemaire
Copy link
AntoineLemaire commented Jan 8, 2018

Same problem here, I can observe the problem in production, we have many logs with Sentry. But I didn't managed to reproduce it yet, Sentry is not very helpful and I don't know what throw the error

Thanks to @polem, we found that we had effectively processes running with supervisor which used the old container
Restart supervisor fixed the problem

@nicolas-grekas
Copy link
Member
nicolas-grekas commented Jan 9, 2018

@fancyweb @coudenysj could you please confirm that your case is fixed by #25733?

fabpot added a commit that referenced this issue Jan 10, 2018
…fresh again (nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[HttpKernel] Fix compile error when a legacy container is fresh again

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

Noticed by @jpauli again: when reverting some configuration changes ends up generating the same container as the previously legacy one, the legacy flag should be removed.

Commits
-------

8c3eadb [HttpKernel] Fix compile error when a legacy container is fresh again
@fancyweb
Copy link
Contributor

It doesn't fix it for me but I guess the problem could also be in the way I deploy or in my setup.
I use a shell script with the following content :

sudo ./stop_sv_services.sh
cd /path/to/my/site/dir
git pull origin prod
composer install --no-dev --optimize-autoloader
php bin/console doctrine:migrations:migrate -n
php bin/console assetic:dump
php bin/console doctrine:cache:clear-metadata
php bin/console doctrine:cache:clear-result
php bin/console doctrine:cache:clear-query
php bin/console cache:clear
php bin/console cache:warmup
sudo ./start_sv_services.sh

I use runsv to run commands continually. The stop_sv_services and start_sv_services scripts are used to restart them when I deploy. I changed it recently to try to fix this problem but back in 3.3 I had only one script that restarted them at the end and it was working.
This shell script is started from a Symfony command with a Process as in my previous message. If I run this command I get the error. However if I directly run the script there is no error. Also ofc if I comment the cache:clear there is also no error.

@coudenysj
Copy link
Author

This is exactly where the problem lies. If you have long running processes, you will hit this error.

The processes have a path to the old container in memory, which doesn't exist anymore after a cache rebuild.

I try to solve it by stopping the long running processes (Symfony commands) before I rebuild the cache, and start them again afterwards.

This still sometimes gives me an error when someone clears the cache directly via the commands, so this change is kind of annoying.

@coudenysj coudenysj reopened this Jan 11, 2018
@nicolas-grekas
Copy link
Member
nicolas-grekas commented Jan 11, 2018

There is no fix to this on Symfony's side: if the underlying code changes, you must restart your long running processes. No way around.

@nicolas-grekas
Copy link
Member

(it could happen with any class really)
The good news is that the name of the cache folder should be immutable for the same configuration now, so that clearing the cache while not actually changing anything should not break your long running processes.
If the name is not stable, look at non-core bundles.

@fancyweb
Copy link
Contributor

The processes are restarted (stopped before cache:clear and then started again). Also why the error doesn't appear when the script is directly executed ?

@coudenysj
Copy link
Author
coudenysj commented Jan 11, 2018

Just as a clarification for users having the same issue:

The problem lies in the fact that Symfony changes the class name of the generated container (and thus changes the filename).

When you have long running scripts, they have the old container file open (in memory), but it does not exist anymore. You could check this with lsof -p PID.

The process keeps running, until you ask it to do something, and then it crashes (because it tries to load the container file, which is gone).

In the older versions of Symfony, the container file was just loaded again (because the filename was the same) and everything worked fine.

Something to keep in mind.

@nicolas-grekas
Copy link
Member
nicolas-grekas commented Jan 11, 2018

In the older versions of Symfony, the file was just loaded again

Actually, it was not loaded again: the old file was still loaded and used for the whole life of the process.
Thus, it contained potentially obsolete service factories, potentially leading to other kind of bugs for these processes (less visible ones.)

@nicolas-grekas
Copy link
Member
nicolas-grekas commented Jan 11, 2018

@fancyweb btw your snippet is strange: cache:clear should have --no-warmup if you warmup just after (but note that it's also fine since 3.3/3.4 to just cache:clear and let it are about warmups.
The second thing that is strange is running migrations before clearing the cache.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants
0