added a cache warmer sub-framework
Cache warmer will come in the next commits. To warm up the cache on a production server, you can use the cache:warmup command: ./app/console_prod cache:warmup
This commit is contained in:
parent
04e16e433d
commit
d0b4bfc8f6
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Command;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Warmup the cache.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class CacheWarmupCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @see Command
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('cache:warmup')
|
||||
->setDescription('Warms up an empty cache')
|
||||
->setHelp(<<<EOF
|
||||
The <info>cache:warmup</info> command warms up the cache.
|
||||
|
||||
Before running this command, the cache must be empty.
|
||||
EOF
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('Warming up the cache');
|
||||
|
||||
$warmer = $this->container->get('cache_warmer');
|
||||
$warmer->enableOptionalWarmers();
|
||||
$warmer->warmUp($this->container->getParameter('kernel.cache_dir'));
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Registers the cache warmers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class AddCacheWarmerPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('cache_warmer')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$warmers = array();
|
||||
foreach ($container->findTaggedServiceIds('kernel.cache_warmer') as $id => $attributes) {
|
||||
$warmers[] = new Reference($id);
|
||||
}
|
||||
|
||||
$container->getDefinition('cache_warmer')->setArgument(0, $warmers);
|
||||
|
||||
if ('full' === $container->getParameter('kernel.cache_warmup')) {
|
||||
$container->getDefinition('cache_warmer')->addMethodCall('enableOptionalWarmers', array());
|
||||
}
|
||||
}
|
||||
}
|
@ -157,6 +157,13 @@ class FrameworkExtension extends Extension
|
||||
$this->registerEsiConfiguration($config, $container);
|
||||
}
|
||||
|
||||
if (isset($config['cache-warmer'])) {
|
||||
$config['cache_warmer'] = $config['cache-warmer'];
|
||||
}
|
||||
|
||||
$warmer = isset($config['cache_warmer']) ? $config['cache_warmer'] : !$container->getParameter('kernel.debug');
|
||||
$container->setParameter('kernel.cache_warmup', $warmer);
|
||||
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\HttpFoundation\\ParameterBag',
|
||||
'Symfony\\Component\\HttpFoundation\\HeaderBag',
|
||||
@ -276,7 +283,6 @@ class FrameworkExtension extends Extension
|
||||
|
||||
// compilation
|
||||
$this->addClassesToCompile(array(
|
||||
'Symfony\\Component\\Templating\\DelegatingEngine',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface',
|
||||
'Symfony\\Component\\Templating\\EngineInterface',
|
||||
));
|
||||
|
@ -21,6 +21,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverP
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddClassesToCachePass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
@ -82,6 +83,7 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new AddFieldFactoryGuessersPass());
|
||||
$container->addCompilerPass(new AddClassesToCachePass());
|
||||
$container->addCompilerPass(new TranslatorPass());
|
||||
$container->addCompilerPass(new AddCacheWarmerPass());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,17 @@
|
||||
<xsd:attribute name="ide" type="xsd:string" />
|
||||
<xsd:attribute name="charset" type="xsd:string" />
|
||||
<xsd:attribute name="error-handler" type="xsd:string" />
|
||||
<xsd:attribute name="cache-warmer" type="cache_warmer" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="cache_warmer">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="false" />
|
||||
<xsd:enumeration value="true" />
|
||||
<xsd:enumeration value="full" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="profiler">
|
||||
<xsd:all>
|
||||
<xsd:element name="matcher" type="profiler_matcher" minOccurs="0" maxOccurs="1" />
|
||||
|
@ -11,6 +11,7 @@
|
||||
<parameter key="error_handler.class">Symfony\Component\HttpKernel\Debug\ErrorHandler</parameter>
|
||||
<parameter key="error_handler.level">null</parameter>
|
||||
<parameter key="filesystem.class">Symfony\Bundle\FrameworkBundle\Util\Filesystem</parameter>
|
||||
<parameter key="cache_warmer.class">Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
@ -28,6 +29,10 @@
|
||||
<call method="setEventDispatcher"><argument type="service" id="event_dispatcher" /></call>
|
||||
</service>
|
||||
|
||||
<service id="cache_warmer" class="%cache_warmer.class%">
|
||||
<argument type="collection" />
|
||||
</service>
|
||||
|
||||
<!--
|
||||
If you want to change the Request class, modify the code in
|
||||
your front controller (app.php) so that it passes an instance of
|
||||
|
31
src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php
Normal file
31
src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.org>
|
||||
*/
|
||||
abstract class CacheWarmer implements CacheWarmerInterface
|
||||
{
|
||||
protected function writeCacheFile($file, $content)
|
||||
{
|
||||
$tmpFile = tempnam(dirname($file), basename($file));
|
||||
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
|
||||
chmod($file, 0644);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.org>
|
||||
*/
|
||||
class CacheWarmerAggregate implements CacheWarmerInterface
|
||||
{
|
||||
protected $warmers;
|
||||
protected $optionalsEnabled;
|
||||
|
||||
public function __construct(array $warmers = array())
|
||||
{
|
||||
$this->setWarmers($warmers);
|
||||
$this->optionalsEnabled = false;
|
||||
}
|
||||
|
||||
public function enableOptionalWarmers()
|
||||
{
|
||||
$this->optionalsEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms up the cache.
|
||||
*
|
||||
* @param string $cacheDir The cache directory
|
||||
*/
|
||||
public function warmUp($cacheDir)
|
||||
{
|
||||
foreach ($this->warmers as $warmer) {
|
||||
if (!$this->optionalsEnabled && $warmer->isOptional()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$warmer->warmUp($cacheDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this warmer is optional or not.
|
||||
*
|
||||
* @return Boolean always true
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setWarmers(array $warmers)
|
||||
{
|
||||
$this->warmers = array();
|
||||
foreach ($warmers as $warmer) {
|
||||
$this->add($warmer);
|
||||
}
|
||||
}
|
||||
|
||||
public function add(CacheWarmerInterface $warmer)
|
||||
{
|
||||
$this->warmers[] = $warmer;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.org>
|
||||
*/
|
||||
interface CacheWarmerInterface
|
||||
{
|
||||
/**
|
||||
* Warms up the cache.
|
||||
*
|
||||
* @param string $cacheDir The cache directory
|
||||
*/
|
||||
function warmUp($cacheDir);
|
||||
|
||||
/**
|
||||
* Checks whether this warmer is optional or not.
|
||||
*
|
||||
* Optional warmers can be ignored on certain conditions.
|
||||
*
|
||||
* A warmer should return true if the cache can be
|
||||
* generated incrementally and on-demand.
|
||||
*
|
||||
* @return Boolean true if the warmer is optional, false otherwise
|
||||
*/
|
||||
function isOptional();
|
||||
}
|
@ -427,15 +427,22 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
|
||||
$location = $this->getCacheDir().'/'.$class;
|
||||
$reload = $this->debug ? $this->needsReload($class, $location) : false;
|
||||
|
||||
$fresh = false;
|
||||
if ($reload || !file_exists($location.'.php')) {
|
||||
$container = $this->buildContainer();
|
||||
$this->dumpContainer($container, $class, $location.'.php');
|
||||
|
||||
$fresh = true;
|
||||
}
|
||||
|
||||
require_once $location.'.php';
|
||||
|
||||
$this->container = new $class();
|
||||
$this->container->set('kernel', $this);
|
||||
|
||||
if ($fresh && 'cli' !== php_sapi_name()) {
|
||||
$this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
|
||||
}
|
||||
}
|
||||
|
||||
public function getKernelParameters()
|
||||
|
Reference in New Issue
Block a user