minor #35109 [FrameworkBundle] cache ClassMetadataFactory in debug (bastnic)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[FrameworkBundle] cache ClassMetadataFactory in debug

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no (performance)
| New feature?  | performance...
| Deprecations? | no
| Tickets       | #35096
| License       | MIT
| Doc PR        |

Cf #35096, validator and serialization yaml/xml files are parsed at each requests. But they are already tracked by a `DirectoryResource` in
bd9dc7c573/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php (L1246-L1261)

So it only needs a real cache purge on validator / serializer sytem cache, and I use the [CachePoolClearerCacheWarmer](https://github.com/api-platform/core/blob/master/src/Bridge/Symfony/Bundle/CacheWarmer/CachePoolClearerCacheWarmer.php) from APIP that already does similar things.

Handling that sort of cache in Symfony fixes a lot of others performance issue.

![image](https://user-images.githubusercontent.com/84887/71452294-e6869480-2783-11ea-9aa8-431db3edfd8d.png)

Commits
-------

53324986cb [FrameworkBundle] cache ClassMetadataFactory in debug
This commit is contained in:
Fabien Potencier 2020-01-07 20:35:07 +01:00
commit e781cd8283
4 changed files with 69 additions and 6 deletions

View File

@ -0,0 +1,57 @@
<?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\Bundle\FrameworkBundle\CacheWarmer;
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
/**
* Clears the cache pools when warming up the cache.
*
* Do not use in production!
*
* @author Kévin Dunglas <dunglas@gmail.com>
*
* @internal
*/
final class CachePoolClearerCacheWarmer implements CacheWarmerInterface
{
private $poolClearer;
private $pools;
public function __construct(Psr6CacheClearer $poolClearer, array $pools = [])
{
$this->poolClearer = $poolClearer;
$this->pools = $pools;
}
/**
* {@inheritdoc}
*/
public function warmUp($cacheDirectory): void
{
foreach ($this->pools as $pool) {
if ($this->poolClearer->hasPool($pool)) {
$this->poolClearer->clearPool($pool);
}
}
}
/**
* {@inheritdoc}
*/
public function isOptional(): bool
{
// optional cache warmers are not run when handling the request
return false;
}
}

View File

@ -1457,10 +1457,6 @@ class FrameworkExtension extends Extension
$chainLoader->replaceArgument(0, $serializerLoaders);
$container->getDefinition('serializer.mapping.cache_warmer')->replaceArgument(0, $serializerLoaders);
if ($container->getParameter('kernel.debug')) {
$container->removeDefinition('serializer.mapping.cache_class_metadata_factory');
}
if (isset($config['name_converter']) && $config['name_converter']) {
$container->getDefinition('serializer.name_converter.metadata_aware')->setArgument(1, new Reference($config['name_converter']));
}

View File

@ -11,5 +11,15 @@
<service id="data_collector.cache" class="Symfony\Component\Cache\DataCollector\CacheDataCollector" public="true">
<tag name="data_collector" template="@WebProfiler/Collector/cache.html.twig" id="cache" priority="275" />
</service>
<!-- CacheWarmer used in dev to clear cache pool -->
<service id="cache_pool_clearer.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\CachePoolClearerCacheWarmer" public="false">
<argument type="service" id="cache.system_clearer" />
<argument type="collection">
<argument>cache.validator</argument>
<argument>cache.serializer</argument>
</argument>
<tag name="kernel.cache_warmer" priority="64" />
</service>
</services>
</container>

View File

@ -1102,10 +1102,10 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertEquals(new Reference('serializer.mapping.cache.symfony'), $cache);
}
public function testSerializerCacheDisabled()
public function testSerializerCacheActivatedDebug()
{
$container = $this->createContainerFromFile('serializer_enabled', ['kernel.debug' => true, 'kernel.container_class' => __CLASS__]);
$this->assertFalse($container->hasDefinition('serializer.mapping.cache_class_metadata_factory'));
$this->assertTrue($container->hasDefinition('serializer.mapping.cache_class_metadata_factory'));
}
public function testSerializerMapping()