[HttpKernel][FrameworkBundle] Add RebootableInterface, fix and un-deprecate cache:clear with warmup
This commit is contained in:
parent
f751ac9ac1
commit
a4fc49294e
@ -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
|
||||
-------
|
||||
|
||||
|
@ -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
|
||||
----
|
||||
|
||||
|
@ -19,6 +19,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -33,6 +34,7 @@ class CacheClearCommand extends ContainerAwareCommand
|
||||
{
|
||||
private $cacheClearer;
|
||||
private $filesystem;
|
||||
private $warning;
|
||||
|
||||
/**
|
||||
* @param CacheClearerInterface $cacheClearer
|
||||
@ -112,6 +114,12 @@ EOF
|
||||
$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()) {
|
||||
@ -167,6 +175,11 @@ EOF
|
||||
{
|
||||
// create a temporary kernel
|
||||
$realKernel = $this->getApplication()->getKernel();
|
||||
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, '\\')) {
|
||||
@ -178,6 +191,7 @@ EOF
|
||||
|
||||
$tempKernelReflection = new \ReflectionObject($tempKernel);
|
||||
$tempKernelFile = $tempKernelReflection->getFileName();
|
||||
}
|
||||
|
||||
// warmup temporary dir
|
||||
$warmer = $tempKernel->getContainer()->get('cache_warmer');
|
||||
@ -186,6 +200,20 @@ EOF
|
||||
}
|
||||
$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);
|
||||
@ -198,16 +226,6 @@ EOF
|
||||
));
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
@ -4,6 +4,7 @@ CHANGELOG
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added `RebootableInterface` and implemented it in `Kernel`
|
||||
* deprecated commands auto registration
|
||||
* added `AddCacheClearerPass`
|
||||
* added `AddCacheWarmerPass`
|
||||
|
@ -43,7 +43,7 @@ use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
abstract class Kernel implements KernelInterface, RebootableInterface, TerminableInterface
|
||||
{
|
||||
/**
|
||||
* @var BundleInterface[]
|
||||
@ -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;
|
||||
@ -127,6 +128,16 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
$this->booted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reboot($warmupDir)
|
||||
{
|
||||
$this->shutdown();
|
||||
$this->warmupDir = $warmupDir;
|
||||
$this->boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -373,7 +384,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
@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)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -381,7 +392,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
*/
|
||||
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)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -424,9 +435,10 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,7 +548,8 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
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) {
|
||||
@ -580,8 +593,8 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
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()) : '');
|
||||
}
|
||||
}
|
||||
|
||||
@ -636,7 +649,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
'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,
|
||||
@ -682,7 +695,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
*/
|
||||
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));
|
||||
@ -786,9 +799,6 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
@chmod($dir.$file, 0666 & ~umask());
|
||||
}
|
||||
|
||||
// track changes made to the container directory
|
||||
$container->fileExists(dirname($dir.$file));
|
||||
|
||||
$cache->write($rootCode, $container->getResources());
|
||||
}
|
||||
|
||||
|
30
src/Symfony/Component/HttpKernel/RebootableInterface.php
Normal file
30
src/Symfony/Component/HttpKernel/RebootableInterface.php
Normal file
@ -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);
|
||||
}
|
Reference in New Issue
Block a user