Skip to content

Commit

Permalink
feature #31452 [FrameworkBundle] Add cache configuration for Property…
Browse files Browse the repository at this point in the history
…Info (alanpoulain)

This PR was squashed before being merged into the 4.3 branch (closes #31452).

Discussion
----------

[FrameworkBundle] Add cache configuration for PropertyInfo

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? |
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

The PropertyInfoExtractor was not cached by default but the class to do it was surprisingly here, unused.

I've added the configuration to enable it by default when it's not the development environment.

I haven't added the warmup part because there are too much arguments for the methods (class, property, context).

It will be a big boost for the performance! For this code:

```php
$book = $this->serializer->deserialize('{"id":3,"reviews":[{"id": 7, "body": "This book is fantastic!", "rating": 9, "letter": "A", "publicationDate": "2019"}],"isbn":"978-0-5533-9243-2","title":"Fool\'s Assassin","description":"A famous saga","author":"Robin Hobb","publicationDate":"2014"}', Book::class, 'json');
$this->serializer->serialize($book, 'json');
```

We obtain this:

![image](https://user-images.githubusercontent.com/10920253/57487994-2874d000-72b2-11e9-92a2-28b14a038194.png)

The Blackfire comparison is here: https://blackfire.io/profiles/compare/2c746d26-320a-4aab-80ef-7276c2e92b96/graph

Commits
-------

17f6225 [FrameworkBundle] Add cache configuration for PropertyInfo
  • Loading branch information
fabpot committed May 13, 2019
2 parents 0d196c4 + 17f6225 commit 3a17701
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 13 deletions.
Expand Up @@ -99,7 +99,6 @@
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer;
use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
Expand Down Expand Up @@ -1505,18 +1504,8 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
$chainLoader->replaceArgument(0, $serializerLoaders);
$container->getDefinition('serializer.mapping.cache_warmer')->replaceArgument(0, $serializerLoaders);

if (!$container->getParameter('kernel.debug')) {
$cacheMetadataFactory = new Definition(
CacheClassMetadataFactory::class,
[
new Reference('serializer.mapping.cache_class_metadata_factory.inner'),
new Reference('serializer.mapping.cache.symfony'),
]
);
$cacheMetadataFactory->setPublic(false);
$cacheMetadataFactory->setDecoratedService('serializer.mapping.class_metadata_factory');

$container->setDefinition('serializer.mapping.cache_class_metadata_factory', $cacheMetadataFactory);
if ($container->getParameter('kernel.debug')) {
$container->removeDefinition('serializer.mapping.cache_class_metadata_factory');
}

if (isset($config['name_converter']) && $config['name_converter']) {
Expand Down Expand Up @@ -1551,6 +1540,10 @@ private function registerPropertyInfoConfiguration(ContainerBuilder $container,
$definition->addTag('property_info.description_extractor', ['priority' => -1000]);
$definition->addTag('property_info.type_extractor', ['priority' => -1001]);
}

if ($container->getParameter('kernel.debug')) {
$container->removeDefinition('property_info.cache');
}
}

private function registerLockConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
Expand Down
4 changes: 4 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml
Expand Up @@ -36,6 +36,10 @@
<tag name="cache.pool" />
</service>

<service id="cache.property_info" parent="cache.system" public="false">
<tag name="cache.pool" />
</service>

<service id="cache.messenger.restart_workers_signal" parent="cache.app" public="false">
<tag name="cache.pool" />
</service>
Expand Down
Expand Up @@ -21,6 +21,11 @@
<service id="Symfony\Component\PropertyInfo\PropertyListExtractorInterface" alias="property_info" />
<service id="Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface" alias="property_info" />

<service id="property_info.cache" decorates="property_info" class="Symfony\Component\PropertyInfo\PropertyInfoCacheExtractor">
<argument type="service" id="property_info.cache.inner" />
<argument type="service" id="cache.property_info" />
</service>

<!-- Extractor -->
<service id="property_info.reflection_extractor" class="Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor">
<tag name="property_info.list_extractor" priority="-1000" />
Expand Down
Expand Up @@ -104,6 +104,11 @@
<argument type="service" id="cache.serializer" />
</service>

<service id="serializer.mapping.cache_class_metadata_factory" decorates="serializer.mapping.class_metadata_factory" class="Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory">
<argument type="service" id="serializer.mapping.cache_class_metadata_factory.inner" />
<argument type="service" id="serializer.mapping.cache.symfony" />
</service>

<!-- Encoders -->
<service id="serializer.encoder.xml" class="Symfony\Component\Serializer\Encoder\XmlEncoder">
<tag name="serializer.encoder" />
Expand Down
Expand Up @@ -1357,6 +1357,22 @@ public function testPropertyInfoEnabled()
$this->assertTrue($container->has('property_info'));
}

public function testPropertyInfoCacheActivated()
{
$container = $this->createContainerFromFile('property_info');

$this->assertTrue($container->hasDefinition('property_info.cache'));

$cache = $container->getDefinition('property_info.cache')->getArgument(1);
$this->assertEquals(new Reference('cache.property_info'), $cache);
}

public function testPropertyInfoCacheDisabled()
{
$container = $this->createContainerFromFile('property_info', ['kernel.debug' => true, 'kernel.container_class' => __CLASS__]);
$this->assertFalse($container->hasDefinition('property_info.cache'));
}

public function testEventDispatcherService()
{
$container = $this->createContainer(['kernel.charset' => 'UTF-8', 'kernel.secret' => 'secret']);
Expand Down

0 comments on commit 3a17701

Please sign in to comment.