From 1f069b94c76e3496a5c76a03a6434512ee7a8990 Mon Sep 17 00:00:00 2001 From: Gocha Ossinkine Date: Thu, 20 Aug 2020 21:28:51 +0500 Subject: [PATCH] Add PhpArrayAdapter to cache metadata --- CacheWarmer/DoctrineMetadataCacheWarmer.php | 39 +++++++++++++++++++ DependencyInjection/DoctrineExtension.php | 37 ++++++++++++++++++ .../DoctrineExtensionTest.php | 20 ++++++++-- 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 CacheWarmer/DoctrineMetadataCacheWarmer.php diff --git a/CacheWarmer/DoctrineMetadataCacheWarmer.php b/CacheWarmer/DoctrineMetadataCacheWarmer.php new file mode 100644 index 000000000..bb308c878 --- /dev/null +++ b/CacheWarmer/DoctrineMetadataCacheWarmer.php @@ -0,0 +1,39 @@ +entityManager = $entityManager; + + parent::__construct($phpArrayFile); + } + + /** + * @param string $cacheDir + * + * @return bool false if there is nothing to warm-up + */ + protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter) + { + $metadataFactory = new ClassMetadataFactory(); + $metadataFactory->setEntityManager($this->entityManager); + $metadataFactory->setCacheDriver(new DoctrineProvider($arrayAdapter)); + $metadataFactory->getAllMetadata(); + + return true; + } +} diff --git a/DependencyInjection/DoctrineExtension.php b/DependencyInjection/DoctrineExtension.php index 707495a1c..ae263f6c2 100644 --- a/DependencyInjection/DoctrineExtension.php +++ b/DependencyInjection/DoctrineExtension.php @@ -2,6 +2,7 @@ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; +use Doctrine\Bundle\DoctrineBundle\CacheWarmer\DoctrineMetadataCacheWarmer; use Doctrine\Bundle\DoctrineBundle\Dbal\RegexSchemaAssetFilter; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass; use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; @@ -17,6 +18,8 @@ use Symfony\Bridge\Doctrine\SchemaListener\PdoCacheAdapterDoctrineSchemaSubscriber; use Symfony\Bridge\Doctrine\Validator\DoctrineLoader; use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\DoctrineAdapter; +use Symfony\Component\Cache\Adapter\PhpArrayAdapter; use Symfony\Component\Cache\DoctrineProvider; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Alias; @@ -778,6 +781,11 @@ protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $c $this->loadCacheDriver('metadata_cache', $entityManager['name'], $entityManager['metadata_cache_driver'], $container); $this->loadCacheDriver('result_cache', $entityManager['name'], $entityManager['result_cache_driver'], $container); $this->loadCacheDriver('query_cache', $entityManager['name'], $entityManager['query_cache_driver'], $container); + + if (!$container->getParameter('kernel.debug')) { + $this->registerMetadataPhpArrayCacheWarmer($entityManager['name'], $container); + $this->registerMetadataPhpArrayCache($entityManager['name'], $container); + } } /** @@ -898,4 +906,33 @@ private function createArrayAdapterCachePool(ContainerBuilder $container, string return $id; } + + private function registerMetadataPhpArrayCacheWarmer(string $entityManagerName, ContainerBuilder $container): void + { + $cacheWarmerDefinition = $container->register(sprintf('doctrine.orm.%s_metadata_cache.php_array_warmer', $entityManagerName), DoctrineMetadataCacheWarmer::class); + $cacheWarmerDefinition->setArguments([ + new Reference(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName)), + $this->getPhpArrayFile($entityManagerName) + ]); + $cacheWarmerDefinition->addTag('kernel.cache_warmer'); + } + + private function registerMetadataPhpArrayCache(string $entityManagerName, ContainerBuilder $container): void + { + $aliasId = sprintf('doctrine.orm.%s_metadata_cache', $entityManagerName); + $serviceId = (string) $container->getAlias($aliasId); + $phpArrayAdapterDefinition = new Definition(PhpArrayAdapter::class, [ + $this->getPhpArrayFile($entityManagerName), + new Definition(DoctrineAdapter::class, [new Reference($serviceId)]), + ]); + $serviceId = $serviceId.'.php_array'; + $doctrineCacheDefinition = $container->register($serviceId, DoctrineProvider::class); + $doctrineCacheDefinition->addArgument($phpArrayAdapterDefinition); + $container->setAlias($aliasId, $serviceId); + } + + private function getPhpArrayFile(string $entityManagerName): string + { + return '%kernel.cache_dir%'.sprintf('/doctrine/orm/%s_metadata.php', $entityManagerName); + } } diff --git a/Tests/DependencyInjection/DoctrineExtensionTest.php b/Tests/DependencyInjection/DoctrineExtensionTest.php index 06ad2356a..3a72c51a1 100644 --- a/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -11,6 +11,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\Messenger\DoctrineClearEntityManagerWorkerSubscriber; use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\DoctrineAdapter; +use Symfony\Component\Cache\Adapter\PhpArrayAdapter; use Symfony\Component\Cache\DoctrineProvider; use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -326,6 +328,18 @@ public function testDependencyInjectionConfigurationDefaults() : void $definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache')); $this->assertEquals(DoctrineProvider::class, $definition->getClass()); $arguments = $definition->getArguments(); + $this->assertInstanceOf(Definition::class, $arguments[0]); + $this->assertEquals(PhpArrayAdapter::class, $arguments[0]->getClass()); + $arguments = $arguments[0]->getArguments(); + $this->assertSame('%kernel.cache_dir%/doctrine/orm/default_metadata.php', $arguments[0]); + $this->assertInstanceOf(Definition::class, $arguments[1]); + $this->assertEquals(DoctrineAdapter::class, $arguments[1]->getClass()); + $arguments = $arguments[1]->getArguments(); + $this->assertInstanceOf(Reference::class, $arguments[0]); + $this->assertEquals('doctrine.orm.cache.provider.cache.doctrine.orm.default.metadata', (string) $arguments[0]); + $definition = $container->getDefinition((string) $arguments[0]); + $this->assertEquals(DoctrineProvider::class, $definition->getClass()); + $arguments = $definition->getArguments(); $this->assertInstanceOf(Reference::class, $arguments[0]); $this->assertEquals('cache.doctrine.orm.default.metadata', (string) $arguments[0]); $this->assertSame(ArrayAdapter::class, $container->getDefinition((string) $arguments[0])->getClass()); @@ -730,7 +744,7 @@ public static function cacheConfigurationProvider() : array return [ 'metadata_cache_default' => [ 'expectedAliasName' => 'doctrine.orm.default_metadata_cache', - 'expectedAliasTarget' => 'doctrine.orm.cache.provider.cache.doctrine.orm.default.metadata', + 'expectedAliasTarget' => 'doctrine.orm.cache.provider.cache.doctrine.orm.default.metadata.php_array', 'cacheName' => 'metadata_cache_driver', 'cacheConfig' => ['type' => null], ], @@ -749,7 +763,7 @@ public static function cacheConfigurationProvider() : array 'metadata_cache_pool' => [ 'expectedAliasName' => 'doctrine.orm.default_metadata_cache', - 'expectedAliasTarget' => 'doctrine.orm.cache.provider.metadata_cache_pool', + 'expectedAliasTarget' => 'doctrine.orm.cache.provider.metadata_cache_pool.php_array', 'cacheName' => 'metadata_cache_driver', 'cacheConfig' => ['type' => 'pool', 'pool' => 'metadata_cache_pool'], ], @@ -768,7 +782,7 @@ public static function cacheConfigurationProvider() : array 'metadata_cache_service' => [ 'expectedAliasName' => 'doctrine.orm.default_metadata_cache', - 'expectedAliasTarget' => 'service_target_metadata', + 'expectedAliasTarget' => 'service_target_metadata.php_array', 'cacheName' => 'metadata_cache_driver', 'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'], ],