Skip to content

Commit 1164bc8

Browse files
bug #49679 [FrameworkBundle] enable metadata cache when annotation is disabled (bastnic)
This PR was merged into the 5.4 branch. Discussion ---------- [FrameworkBundle] enable metadata cache when annotation is disabled | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead --> | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> When using Annotations, annotations are cached at `AnnotationLoader` level. Which is cleared when entities are changed. So the dev experience is optimal. ``` [ClassMetadataFactory.php](vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php") on line 51: [Symfony\Component\Serializer\Mapping\Loader\LoaderChain](vendor/symfony/serializer/Mapping/Loader/LoaderChain.php&line=28#line28) {#543 ▼ -loaders: array:1 [▼ 0 => [Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader](vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php&line=33#line33) {#544 ▼ -reader: [Doctrine\Common\Annotations\PsrCachedReader](vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php&line=22#line22) {#262 ▼ -delegate: [Doctrine\Common\Annotations\AnnotationReader](vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php&line=20#line20) {#263 ▶} -cache: [Symfony\Component\Cache\Adapter\PhpArrayAdapter](vendor/symfony/cache/Adapter/PhpArrayAdapter.php&line=32#line32) {#277 ▶} -debug: true -loadedAnnotations: array:14 [▶] -loadedFilemtimes: array:4 [▶] } } ] } ``` When using yaml files, there is no cache at the loader level so I added in the past the same cache as for the prod env, as the metadata are effectively cleared when using only yaml config files. symfony/symfony#35109 The regression introduced by my patch is for people that do not use mapping files but use annotations. symfony/symfony#41961 But now, we are in the opposite situation: no cache for people using mapping files but not annotations. On a current project it means loading 83 yaml files for each dev requests. It's not good at all. A simple local fix is to add that in a dev services files. ```yaml serializer.mapping.cache_class_metadata_factory: class: 'Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory' decorates: 'serializer.mapping.class_metadata_factory' arguments: ['`@serializer`.mapping.cache_class_metadata_factory.inner', '`@serializer`.mapping.cache.symfony'] ``` ![image](https://user-images.githubusercontent.com/84887/224833940-b8e7ad72-e7f6-44e7-a924-0b20f2f0cdae.png) A solution in Symfony could be: 1/ only yaml/xml mapping files (`enable_annotations: false`) : cache like prod => that what I did in this PR, as it fixes the current perf regressions on my different projects. There is no cache on yaml/xml file as soon as annotation is enabled (which is the default) 2/ add a cache at reader level for yaml/xml loader 3/ add a cache cleaner at metadata level when annotation are enabled Commits ------- 1773dff5ce [FrameworkBundle] enable metadata cache when annotation is disabled
2 parents 3393606 + b5e22bb commit 1164bc8

File tree

5 files changed

+49
-5
lines changed

5 files changed

+49
-5
lines changed

DependencyInjection/FrameworkExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,9 +1769,6 @@ private function registerSecurityCsrfConfiguration(array $config, ContainerBuild
17691769
private function registerSerializerConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader)
17701770
{
17711771
$loader->load('serializer.php');
1772-
if ($container->getParameter('kernel.debug')) {
1773-
$container->removeDefinition('serializer.mapping.cache_class_metadata_factory');
1774-
}
17751772

17761773
$chainLoader = $container->getDefinition('serializer.mapping.chain_loader');
17771774

@@ -1797,6 +1794,9 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
17971794
if (\PHP_VERSION_ID < 80000 && !$this->annotationsConfigEnabled) {
17981795
throw new \LogicException('"enable_annotations" on the serializer cannot be set as the PHP version is lower than 8 and Annotations support is disabled. Consider upgrading PHP.');
17991796
}
1797+
if ($container->getParameter('kernel.debug')) {
1798+
$container->removeDefinition('serializer.mapping.cache_class_metadata_factory');
1799+
}
18001800

18011801
$annotationLoader = new Definition(
18021802
'Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader',
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'serializer' => [
5+
'enable_annotations' => false,
6+
'mapping' => [
7+
'paths' => [
8+
'%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/files',
9+
'%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/serialization.yml',
10+
'%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/serialization.yaml',
11+
],
12+
],
13+
],
14+
]);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:framework="http://symfony.com/schema/dic/symfony">
6+
7+
<framework:config>
8+
<framework:serializer enable-annotations="false">
9+
<framework:mapping>
10+
<framework:path>%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/files</framework:path>
11+
<framework:path>%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/serialization.yml</framework:path>
12+
<framework:path>%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/serialization.yaml</framework:path>
13+
</framework:mapping>
14+
</framework:serializer>
15+
</framework:config>
16+
</container>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
framework:
2+
serializer:
3+
enable_annotations: false
4+
mapping:
5+
paths:
6+
- "%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/files"
7+
- "%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/serialization.yml"
8+
- "%kernel.project_dir%/Fixtures/TestBundle/Resources/config/serializer_mapping/serialization.yaml"

Tests/DependencyInjection/FrameworkExtensionTestCase.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,9 +1527,15 @@ public function testSerializerCacheActivated()
15271527
$this->assertEquals(new Reference('serializer.mapping.cache.symfony'), $cache);
15281528
}
15291529

1530-
public function testSerializerCacheNotActivatedDebug()
1530+
public function testSerializerCacheUsedWithoutAnnotationsAndMappingFiles()
15311531
{
1532-
$container = $this->createContainerFromFile('serializer_enabled', ['kernel.debug' => true, 'kernel.container_class' => __CLASS__]);
1532+
$container = $this->createContainerFromFile('serializer_mapping_without_annotations', ['kernel.debug' => true, 'kernel.container_class' => __CLASS__]);
1533+
$this->assertTrue($container->hasDefinition('serializer.mapping.cache_class_metadata_factory'));
1534+
}
1535+
1536+
public function testSerializerCacheNotActivatedWithAnnotations()
1537+
{
1538+
$container = $this->createContainerFromFile('serializer_mapping', ['kernel.debug' => true, 'kernel.container_class' => __CLASS__]);
15331539
$this->assertFalse($container->hasDefinition('serializer.mapping.cache_class_metadata_factory'));
15341540
}
15351541

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy