Symfony 4, пользовательский сериализатор очень медленный - PullRequest
0 голосов
/ 09 июля 2020

Я обновился с Symfony 3.4 до 4.4.

Поскольку v4.2 setCallbacks () и setCircularReferenceHandler () устарели, я заменил их, передав контекст в ObjectNormalizer.

Фактически это работает, НО когда у меня много сущностей (сотни или тысячи) для сериализации, это занимает более 30 секунд и, очевидно, выдает тайм-аут.

Например, в 3.4 требуется 7 секунд для сериализации 1444 объектов , это занимает +30 секунд в 4.4.

До:

class MyEntitySerializer extends Serializer
{
    public function __construct(ObjectNormalizer $normalizer, JsonEncoder $encoder)
    {
        $dateCallback = function ($dateTime) {
            return $dateTime instanceof \DateTime
                ? date_format($dateTime,'d/m/Y')
                : null;
        };
         $normalizer->setCallbacks([
            'debut' => $dateCallback,
            'fin' => $dateCallback,
            'demandeDate' => $dateCallback,
            'dateCreation' => $dateCallback,
        ]);

        $normalizer->setCircularReferenceHandler(function ($object) {
            if ($object instanceof Affaire) {
                return $object->getCode();
            } elseif ($object instanceof ComplementAffaire) {
                return $object->getDescription();
            }

            return $object->getId();
        }); 

        parent::__construct([$normalizer], [$encoder]);
    }
}

После:

class MyEntitySerializer extends Serializer
{
    public function __construct(ObjectNormalizer $normalizer, JsonEncoder $encoder)
    {
        $dateCallback = function ($dateTime) {
            return $dateTime instanceof \DateTime
                ? date_format($dateTime,'d/m/Y')
                : null;
        };

        $defaultContext = [
            AbstractNormalizer::CALLBACKS => [
                'debut' => $dateCallback,
                'fin' => $dateCallback,
                'demandeDate' => $dateCallback,
                'dateCreation' => $dateCallback,
            ],
            AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object) {
                if ($object instanceof Affaire) {
                    return $object->getCode();
                } elseif ($object instanceof ComplementAffaire) {
                    return $object->getDescription();
                }
                return $object->getId();
            }
        ];

        $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
        $normalizer = new ObjectNormalizer($classMetadataFactory,null,null,null,null,null,$defaultContext);
        parent::__construct([$normalizer], [$encoder]);
    }
}

Я ввел ClassMetadataFactoryInterface и передал его ObjectNormalizer, вот что этот сериализатор выглядит так: введите здесь описание изображения CacheClassMetadataFactory отсутствует. Он работал, как и раньше (так же медленно, как и раньше).

Я попытался удалить var / cache / и vendor /, затем сделал composer install вот установленные версии:

 - Installing composer/package-versions-deprecated (1.8.1): Loading from cache
  - Installing symfony/flex (v1.8.4): Loading from cache
  - Installing squizlabs/php_codesniffer (3.5.5): Loading from cache
  - Installing dealerdirect/phpcodesniffer-composer-installer (v0.6.2): Loading from cache
  - Installing behat/transliterator (v1.3.0): Loading from cache
  - Installing clue/stream-filter (v1.4.1): Loading from cache
  - Installing doctrine/lexer (1.2.1): Loading from cache
  - Installing doctrine/annotations (1.10.3): Loading from cache
  - Installing doctrine/reflection (1.2.1): Loading from cache
  - Installing doctrine/event-manager (1.1.0): Loading from cache
  - Installing doctrine/collections (1.6.6): Loading from cache
  - Installing doctrine/cache (1.10.2): Loading from cache
  - Installing doctrine/persistence (1.3.7): Loading from cache
  - Installing doctrine/inflector (1.4.3): Loading from cache
  - Installing doctrine/common (2.13.3): Loading from cache
  - Installing psr/container (1.0.0): Loading from cache
  - Installing psr/cache (1.0.1): Loading from cache
  - Installing symfony/contracts (v1.1.8): Loading from cache
  - Installing symfony/polyfill-mbstring (v1.17.1): Loading from cache
  - Installing symfony/polyfill-ctype (v1.17.1): Loading from cache
  - Installing symfony/doctrine-bridge (v4.4.10): Loading from cache
  - Installing doctrine/doctrine-cache-bundle (1.4.0): Loading from cache
  - Installing doctrine/instantiator (1.3.1): Loading from cache
  - Installing symfony/polyfill-php80 (v1.17.1): Loading from cache
  - Installing symfony/polyfill-php73 (v1.17.1): Loading from cache
  - Installing symfony/console (v4.4.10): Loading from cache
  - Installing laminas/laminas-zendframework-bridge (1.0.4): Loading from cache
  - Installing laminas/laminas-eventmanager (3.2.1): Loading from cache
  - Installing laminas/laminas-code (3.4.1): Loading from cache
  - Installing ocramius/proxy-manager (2.2.3): Loading from cache
  - Installing doctrine/dbal (2.10.2): Loading from cache
  - Installing doctrine/migrations (v1.8.1): Loading from cache
  - Installing willdurand/jsonp-callback-validator (v1.1.0): Loading from cache
  - Installing symfony/serializer (v4.4.10): Loading from cache
  - Installing symfony/routing (v4.4.10): Loading from cache
  - Installing symfony/deprecation-contracts (v2.1.3): Loading from cache
  - Installing symfony/http-foundation (v5.1.2): Loading from cache
  - Installing symfony/event-dispatcher (v4.4.10): Loading from cache
  - Installing symfony/var-dumper (v5.1.2): Loading from cache
  - Installing psr/log (1.1.3): Loading from cache
  - Installing symfony/debug (v4.4.10): Loading from cache
  - Installing symfony/error-handler (v4.4.10): Loading from cache
  - Installing symfony/http-kernel (v4.4.10): Loading from cache
  - Installing symfony/finder (v5.1.2): Loading from cache
  - Installing symfony/filesystem (v5.1.2): Loading from cache
  - Installing symfony/dependency-injection (v4.4.10): Loading from cache
  - Installing symfony/config (v4.4.10): Loading from cache
  - Installing symfony/var-exporter (v5.1.2): Loading from cache
  - Installing symfony/cache (v5.1.2): Loading from cache
  - Installing symfony/framework-bundle (v4.4.10): Loading from cache
  - Installing friendsofsymfony/jsrouting-bundle (2.6.0): Loading from cache
  - Installing symfony/polyfill-php72 (v1.17.0): Loading from cache
  - Installing symfony/polyfill-intl-idn (v1.17.1): Loading from cache
  - Installing ralouphie/getallheaders (3.0.3): Loading from cache
  - Installing psr/http-message (1.0.1): Loading from cache
  - Installing guzzlehttp/psr7 (1.6.1): Loading from cache
  - Installing guzzlehttp/promises (v1.3.1): Loading from cache
  - Installing guzzlehttp/guzzle (6.5.5): Loading from cache
  - Installing psr/http-factory (1.0.1): Loading from cache
  - Installing http-interop/http-factory-guzzle (1.0.0): Loading from cache
  - Installing symfony/yaml (v5.1.2): Loading from cache
  - Installing incenteev/composer-parameter-handler (v2.1.4): Loading from cache
  - Installing jdorn/sql-formatter (v1.2.17): Loading from cache
  - Installing knplabs/knp-menu (2.6.0): Loading from cache
  - Installing knplabs/knp-menu-bundle (v2.3.0): Loading from cache
  - Installing symfony/process (v5.1.2): Loading from cache
  - Installing knplabs/knp-snappy (v1.2.1): Loading from cache
  - Installing knplabs/knp-snappy-bundle (v1.7.0): Loading from cache
  - Installing php-http/message-factory (v1.0.2): Loading from cache
  - Installing php-http/promise (1.1.0): Loading from cache
  - Installing psr/http-client (1.0.1): Loading from cache
  - Installing sensio/framework-extra-bundle (v5.5.6): Loading from cache
  - Installing paragonie/random_compat (v9.99.99): Loading from cache
  - Installing symfony/polyfill-uuid (v1.17.1): Loading from cache
  - Installing symfony/options-resolver (v5.1.2): Loading from cache
  - Installing php-http/message (1.8.0): Loading from cache
  - Installing php-http/httplug (2.1.0): Loading from cache
  - Installing php-http/discovery (1.9.0): Loading from cache
  - Installing php-http/client-common (2.2.0): Loading from cache
  - Installing php-http/guzzle6-adapter (v2.0.1): Loading from cache
  - Installing jean85/pretty-package-versions (1.5.0): Loading from cache
  - Installing sentry/sentry (2.4.1): Loading from cache
  - Installing symfony/security-core (v4.4.0): Loading from cache
  - Installing sentry/sdk (2.1.0)
  - Installing sentry/sentry-symfony (3.5.2): Loading from cache
  - Installing gedmo/doctrine-extensions (v2.4.41): Loading from cache
  - Installing stof/doctrine-extensions-bundle (v1.4.0): Loading from cache
  - Installing twig/twig (v2.13.0): Loading from cache
  - Installing symfony/twig-bridge (v4.4.10): Loading from cache
  - Installing symfony/debug-bundle (v4.4.10): Loading from cache
  - Installing symfony/dotenv (v4.4.10): Loading from cache
  - Installing symfony/expression-language (v4.4.10): Loading from cache
  - Installing symfony/polyfill-intl-normalizer (v1.17.1): Loading from cache
  - Installing symfony/polyfill-intl-grapheme (v1.17.1): Loading from cache
  - Installing symfony/string (v5.1.2): Loading from cache
  - Installing symfony/inflector (v5.1.2): Loading from cache
  - Installing symfony/mime (v5.1.2): Loading from cache
  - Installing egulias/email-validator (2.1.18): Loading from cache
  - Installing symfony/mailer (v4.4.10): Loading from cache
  - Installing monolog/monolog (2.1.0): Loading from cache
  - Installing symfony/monolog-bridge (v5.1.2): Loading from cache
  - Installing symfony/monolog-bundle (v3.5.0): Loading from cache
  - Installing doctrine/orm (v2.7.3): Loading from cache
  - Installing doctrine/doctrine-bundle (1.12.0): Loading from cache
  - Installing doctrine/doctrine-migrations-bundle (v1.3.2): Loading from cache
  - Installing symfony/orm-pack (v1.0.8): Loading from cache
  - Installing symfony/polyfill-apcu (v1.17.1): Loading from cache
  - Installing symfony/polyfill-iconv (v1.17.1): Loading from cache
  - Installing symfony/polyfill-intl-icu (v1.17.1): Loading from cache
  - Installing symfony/intl (v5.1.2): Loading from cache
  - Installing symfony/property-access (v4.4.10): Loading from cache
  - Installing symfony/security-http (v4.4.6): Loading from cache
  - Installing symfony/security-guard (v4.4.10): Loading from cache
  - Installing symfony/security-csrf (v5.1.2): Loading from cache
  - Installing symfony/security-bundle (v4.4.10): Loading from cache
  - Installing swiftmailer/swiftmailer (v6.2.3): Loading from cache
  - Installing symfony/swiftmailer-bundle (v3.4.0): Loading from cache
  - Installing symfony/twig-bundle (v4.4.10): Loading from cache
  - Installing twig/extra-bundle (v3.0.4): Loading from cache
  - Installing symfony/twig-pack (v1.0.0): Loading from cache
  - Installing symfony/validator (v4.4.10): Loading from cache
  - Installing symfony/asset (v4.4.10): Loading from cache
  - Installing symfony/webpack-encore-bundle (v1.7.3): Loading from cache
  - Installing tecnickcom/tcpdf (6.3.5): Loading from cache
  - Installing symfony/form (v4.4.10): Loading from cache
  - Installing jms/metadata (2.3.0): Loading from cache
  - Installing vich/uploader-bundle (1.14.0): Loading from cache
  - Installing symfony/translation (v4.4.10): Loading from cache
  - Installing willdurand/js-translation-bundle (3.0.1): Loading from cache
  - Installing doctrine/data-fixtures (1.4.3): Loading from cache
  - Installing doctrine/doctrine-fixtures-bundle (3.3.1): Loading from cache
  - Installing nikic/php-parser (v4.6.0): Loading from cache
  - Installing symfony/maker-bundle (v1.19.1): Loading from cache
  - Installing symfony/web-profiler-bundle (v5.0.10): Loading from cache
  - Installing symfony/stopwatch (v5.1.2): Loading from cache
  - Installing symfony/profiler-pack (v1.0.4): Loading from cache

1 Ответ

1 голос
/ 09 июля 2020
• 1000 *
return $container->privates['serializer.mapping.cache_class_metadata_factory'] = new \Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory(
            new \Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory(
                new \Symfony\Component\Serializer\Mapping\Loader\LoaderChain(
                    [
                        0 => new \Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader(
                            ($container->privates['annotations.cached_reader'] ?? $container->getAnnotations_CachedReaderService(
                                ))
                        ),
                    ]
                )
            ),
            \Symfony\Component\Cache\Adapter\PhpArrayAdapter::create(
                ($container->targetDir . '' . '/serialization.php'),
                ($container->privates['cache.serializer'] ?? $container->load('getCache_SerializerService'))
            )
        );

Он использует кеш.

В vendor/symfony/framework-bundle/Resources/config/serializer.xml вы можете увидеть следующее:

        <service id="serializer.mapping.class_metadata_factory" class="Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory">
            <argument type="service" id="serializer.mapping.chain_loader" />
        </service>

        <service id="Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface" alias="serializer.mapping.class_metadata_factory" />
...
        <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>

Сервис serializer.mapping.cache_class_metadata_factory украшает serializer.mapping.class_metadata_factory, имеющий псевдоним Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface.

Таким образом, вы можете внедрить службу '@Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface' в MyEntitySerializer и использовать ее для создания своего экземпляра ObjectNormalizer.

...