Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[HttpKernel][FrameworkBundle] Add RebootableInterface, fix and un-deprecate cache:clear with warmup #23792

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

Merged
merged 1 commit into from
Aug 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions 3 UPGRADE-3.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ HttpKernel
tags: ['console.command']
```

* The `getCacheDir()` method of your kernel should not be called while building the container.
Use the `%kernel.cache_dir%` parameter instead. Not doing so may break the `cache:clear` command.

Process
-------

Expand Down
3 changes: 3 additions & 0 deletions 3 UPGRADE-4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,9 @@ HttpKernel
by Symfony. Use the `%env()%` syntax to get the value of any environment
variable from configuration files instead.

* The `getCacheDir()` method of your kernel should not be called while building the container.
Use the `%kernel.cache_dir%` parameter instead. Not doing so may break the `cache:clear` command.

Ldap
----

Expand Down
58 changes: 38 additions & 20 deletions 58 src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\RebootableInterface;
use Symfony\Component\Finder\Finder;

/**
Expand All @@ -33,6 +34,7 @@ class CacheClearCommand extends ContainerAwareCommand
{
private $cacheClearer;
private $filesystem;
private $warning;

/**
* @param CacheClearerInterface $cacheClearer
Expand Down Expand Up @@ -112,6 +114,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->filesystem->rename($realCacheDir, $oldCacheDir);
} else {
$this->warmupCache($input, $output, $realCacheDir, $oldCacheDir);

if ($this->warning) {
@trigger_error($this->warning, E_USER_DEPRECATED);
$io->warning($this->warning);
$this->warning = null;
}
}

if ($output->isVerbose()) {
Expand Down Expand Up @@ -167,17 +175,23 @@ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = tr
{
// create a temporary kernel
$realKernel = $this->getApplication()->getKernel();
$realKernelClass = get_class($realKernel);
$namespace = '';
if (false !== $pos = strrpos($realKernelClass, '\\')) {
$namespace = substr($realKernelClass, 0, $pos);
$realKernelClass = substr($realKernelClass, $pos + 1);
}
$tempKernel = $this->getTempKernel($realKernel, $namespace, $realKernelClass, $warmupDir);
$tempKernel->boot();
if ($realKernel instanceof RebootableInterface) {
$realKernel->reboot($warmupDir);
$tempKernel = $realKernel;
} else {
$this->warning = 'Calling "cache:clear" with a kernel that does not implement "Symfony\Component\HttpKernel\RebootableInterface" is deprecated since version 3.4 and will be unsupported in 4.0.';
$realKernelClass = get_class($realKernel);
$namespace = '';
if (false !== $pos = strrpos($realKernelClass, '\\')) {
$namespace = substr($realKernelClass, 0, $pos);
$realKernelClass = substr($realKernelClass, $pos + 1);
}
$tempKernel = $this->getTempKernel($realKernel, $namespace, $realKernelClass, $warmupDir);
$tempKernel->boot();

$tempKernelReflection = new \ReflectionObject($tempKernel);
$tempKernelFile = $tempKernelReflection->getFileName();
$tempKernelReflection = new \ReflectionObject($tempKernel);
$tempKernelFile = $tempKernelReflection->getFileName();
}

// warmup temporary dir
$warmer = $tempKernel->getContainer()->get('cache_warmer');
Expand All @@ -186,6 +200,20 @@ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = tr
}
$warmer->warmUp($warmupDir);

// fix references to cached files with the real cache directory name
$search = array($warmupDir, str_replace('\\', '\\\\', $warmupDir));
$replace = str_replace('\\', '/', $realCacheDir);
foreach (Finder::create()->files()->in($warmupDir) as $file) {
$content = str_replace($search, $replace, file_get_contents($file), $count);
if ($count) {
file_put_contents($file, $content);
}
}

if ($realKernel instanceof RebootableInterface) {
return;
}

// fix references to the Kernel in .meta files
$safeTempKernel = str_replace('\\', '\\\\', get_class($tempKernel));
$realKernelFQN = get_class($realKernel);
Expand All @@ -198,16 +226,6 @@ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = tr
));
}

// fix references to cached files with the real cache directory name
$search = array($warmupDir, str_replace('\\', '\\\\', $warmupDir));
$replace = str_replace('\\', '/', $realCacheDir);
foreach (Finder::create()->files()->in($warmupDir) as $file) {
$content = str_replace($search, $replace, file_get_contents($file), $count);
if ($count) {
file_put_contents($file, $content);
}
}

// fix references to container's class
$tempContainerClass = $tempKernel->getContainerClass();
$realContainerClass = $tempKernel->getRealContainerClass();
Expand Down
1 change: 1 addition & 0 deletions 1 src/Symfony/Component/HttpKernel/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
3.4.0
-----

* added `RebootableInterface` and implemented it in `Kernel`
* deprecated commands auto registration
* added `AddCacheClearerPass`
* added `AddCacheWarmerPass`
Expand Down
36 changes: 23 additions & 13 deletions 36 src/Symfony/Component/HttpKernel/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class Kernel implements KernelInterface, TerminableInterface
abstract class Kernel implements KernelInterface, RebootableInterface, TerminableInterface
{
/**
* @var BundleInterface[]
Expand All @@ -61,6 +61,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $loadClassCache;

private $projectDir;
private $warmupDir;

const VERSION = '3.4.0-DEV';
const VERSION_ID = 30400;
Expand Down Expand Up @@ -127,6 +128,16 @@ public function boot()
$this->booted = true;
}

/**
* {@inheritdoc}
*/
public function reboot($warmupDir)
{
$this->shutdown();
$this->warmupDir = $warmupDir;
$this->boot();
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -373,15 +384,15 @@ public function setClassCache(array $classes)
@trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED);
}

file_put_contents($this->getCacheDir().'/classes.map', sprintf('<?php return %s;', var_export($classes, true)));
file_put_contents(($this->warmupDir ?: $this->getCacheDir()).'/classes.map', sprintf('<?php return %s;', var_export($classes, true)));
}

/**
* @internal
*/
public function setAnnotatedClassCache(array $annotatedClasses)
{
file_put_contents($this->getCacheDir().'/annotations.map', sprintf('<?php return %s;', var_export($annotatedClasses, true)));
file_put_contents(($this->warmupDir ?: $this->getCacheDir()).'/annotations.map', sprintf('<?php return %s;', var_export($annotatedClasses, true)));
}

/**
Expand Down Expand Up @@ -424,9 +435,10 @@ protected function doLoadClassCache($name, $extension)
if (\PHP_VERSION_ID >= 70000) {
@trigger_error(__METHOD__.'() is deprecated since version 3.3, to be removed in 4.0.', E_USER_DEPRECATED);
}
$cacheDir = $this->warmupDir ?: $this->getCacheDir();

if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) {
ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension);
if (!$this->booted && is_file($cacheDir.'/classes.map')) {
ClassCollectionLoader::load(include($cacheDir.'/classes.map'), $cacheDir, $name, $this->debug, false, $extension);
}
}

Expand Down Expand Up @@ -536,7 +548,8 @@ protected function getContainerBaseClass()
protected function initializeContainer()
{
$class = $this->getContainerClass();
$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug);
$cacheDir = $this->warmupDir ?: $this->getCacheDir();
$cache = new ConfigCache($cacheDir.'/'.$class.'.php', $this->debug);
$fresh = true;
if (!$cache->isFresh()) {
if ($this->debug) {
Expand Down Expand Up @@ -580,8 +593,8 @@ protected function initializeContainer()
if ($this->debug) {
restore_error_handler();

file_put_contents($this->getCacheDir().'/'.$class.'Deprecations.log', serialize(array_values($collectedLogs)));
file_put_contents($this->getCacheDir().'/'.$class.'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : '');
file_put_contents($cacheDir.'/'.$class.'Deprecations.log', serialize(array_values($collectedLogs)));
file_put_contents($cacheDir.'/'.$class.'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : '');
}
}

Expand Down Expand Up @@ -636,7 +649,7 @@ protected function getKernelParameters()
'kernel.environment' => $this->environment,
'kernel.debug' => $this->debug,
'kernel.name' => $this->name,
'kernel.cache_dir' => realpath($this->getCacheDir()) ?: $this->getCacheDir(),
'kernel.cache_dir' => realpath($cacheDir = $this->warmupDir ?: $this->getCacheDir()) ?: $cacheDir,
'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(),
'kernel.bundles' => $bundles,
'kernel.bundles_metadata' => $bundlesMetadata,
Expand Down Expand Up @@ -682,7 +695,7 @@ protected function getEnvParameters()
*/
protected function buildContainer()
{
foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) {
foreach (array('cache' => $this->warmupDir ?: $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) {
if (!is_dir($dir)) {
if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir));
Expand Down Expand Up @@ -786,9 +799,6 @@ protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container
@chmod($dir.$file, 0666 & ~umask());
}

// track changes made to the container directory
$container->fileExists(dirname($dir.$file));
Copy link
Member Author

@nicolas-grekas nicolas-grekas Aug 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removes a transient test (CacheClearCommandTest::testCacheIsFreshAfterCacheClearedWithWarmup: Meta file "FixtureTestDebugProjectContainer.php.meta" is not fresh)
and allows debugging the container by patching its generated files when needed (I added this code in 3.4. A bad idea.)
If you mess up with the container files, that's your problem :)


$cache->write($rootCode, $container->getResources());
}

Expand Down
30 changes: 30 additions & 0 deletions 30 src/Symfony/Component/HttpKernel/RebootableInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpKernel;

/**
* Allows the Kernel to be rebooted using a temporary cache directory.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
interface RebootableInterface
{
/**
* Reboots a kernel.
*
* The getCacheDir() method of a rebootable kernel should not be called
* while building the container. Use the %kernel.cache_dir% parameter instead.
*
* @param string|null $warmupDir pass null to reboot in the regular cache directory
*/
public function reboot($warmupDir);
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.