Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PhpArrayAdapter to cache metadata #1196

Merged
merged 2 commits into from
Nov 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions CacheWarmer/DoctrineMetadataCacheWarmer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\CacheWarmer;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Symfony\Bundle\FrameworkBundle\CacheWarmer\AbstractPhpFileCacheWarmer;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\DoctrineProvider;

class DoctrineMetadataCacheWarmer extends AbstractPhpFileCacheWarmer
{
/** @var EntityManagerInterface */
private $entityManager;

public function __construct(EntityManagerInterface $entityManager, string $phpArrayFile)
{
$this->entityManager = $entityManager;

parent::__construct($phpArrayFile);
}

/**
* @param string $cacheDir
*/
protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter): bool
{
$metadataFactory = new ClassMetadataFactory();
$metadataFactory->setEntityManager($this->entityManager);
$metadataFactory->setCacheDriver(new DoctrineProvider($arrayAdapter));
$metadataFactory->getAllMetadata();

return true;
}
}
7 changes: 7 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,13 @@ private function getOrmCacheDriverNode(string $name): ArrayNodeDefinition
->scalarNode('pool')->end()
->end();

if ($name === 'metadata_cache_driver') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means we also need to create a new recipe for 2.2?

See https://github.com/symfony/recipes/blob/master/doctrine/doctrine-bundle/1.12/config/packages/prod/doctrine.yaml#L4 (it's used for 2.x currently as well via symlink)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should yes

$node->setDeprecated(...$this->getDeprecationMsg(
'The "metadata_cache_driver" configuration key is deprecated. PHP Array cache is now automatically registered when %kernel.debug% is false.',
greg0ire marked this conversation as resolved.
Show resolved Hide resolved
'2.2'
));
}

return $node;
}

Expand Down
30 changes: 30 additions & 0 deletions DependencyInjection/DoctrineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection;

use Doctrine\Bundle\DoctrineBundle\CacheWarmer\DoctrineMetadataCacheWarmer;
use Doctrine\Bundle\DoctrineBundle\Dbal\ManagerRegistryAwareConnectionProvider;
use Doctrine\Bundle\DoctrineBundle\Dbal\RegexSchemaAssetFilter;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
Expand All @@ -21,6 +22,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;
Expand Down Expand Up @@ -814,6 +817,12 @@ 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')) {
return;
}

$this->registerMetadataPhpArrayCaching($entityManager['name'], $container);
}

/**
Expand Down Expand Up @@ -927,4 +936,25 @@ private function createArrayAdapterCachePool(ContainerBuilder $container, string

return $id;
}

private function registerMetadataPhpArrayCaching(string $entityManagerName, ContainerBuilder $container): void
{
$metadataCacheAlias = $this->getObjectManagerElementName($entityManagerName . '_metadata_cache');
$decoratedMetadataCacheServiceId = (string) $container->getAlias($metadataCacheAlias);
$phpArrayCacheDecoratorServiceId = $decoratedMetadataCacheServiceId . '.php_array';
greg0ire marked this conversation as resolved.
Show resolved Hide resolved
$phpArrayFile = '%kernel.cache_dir%' . sprintf('/doctrine/orm/%s_metadata.php', $entityManagerName);

$container->register(DoctrineMetadataCacheWarmer::class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ossinkine actually this is not working properly for multiple entity managers. I just tried it on one of my bigger projects that uses 2 managers.

Since DoctrineMetadataCacheWarmer::class is the service id it will only work for the last manager and overwrite any previous definitions

->setArguments([new Reference(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName)), $phpArrayFile])
->addTag('kernel.cache_warmer');

$container->setAlias($metadataCacheAlias, $phpArrayCacheDecoratorServiceId);
$container->register($phpArrayCacheDecoratorServiceId, DoctrineProvider::class)
->addArgument(
new Definition(PhpArrayAdapter::class, [
$phpArrayFile,
new Definition(DoctrineAdapter::class, [new Reference($decoratedMetadataCacheServiceId)]),
])
);
}
}
62 changes: 46 additions & 16 deletions Tests/DependencyInjection/DoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,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;
Expand Down Expand Up @@ -347,6 +349,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());
Expand Down Expand Up @@ -752,6 +766,9 @@ public function testMessengerIntegration(): void
}
}

/**
* @group legacy
*/
public function testInvalidCacheConfiguration(): void
{
if (! interface_exists(EntityManagerInterface::class)) {
Expand Down Expand Up @@ -798,15 +815,42 @@ public function testCacheConfiguration(string $expectedAliasName, string $expect
$this->assertEquals($expectedAliasTarget, (string) $alias);
}

public static function cacheConfigurationProvider(): array
/**
* @dataProvider legacyCacheConfigurationProvider
* @group legacy
*/
public function testLegacyCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, array $cacheConfig): void
{
$this->testCacheConfiguration($expectedAliasName, $expectedAliasTarget, $cacheName, $cacheConfig);
}

public static function legacyCacheConfigurationProvider(): 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],
],
'metadata_cache_pool' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'doctrine.orm.cache.provider.metadata_cache_pool.php_array',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => 'pool', 'pool' => 'metadata_cache_pool'],
],
'metadata_cache_service' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'service_target_metadata.php_array',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
],
];
}

public static function cacheConfigurationProvider(): array
{
return [
'query_cache_default' => [
'expectedAliasName' => 'doctrine.orm.default_query_cache',
'expectedAliasTarget' => 'doctrine.orm.cache.provider.cache.doctrine.orm.default.query',
Expand All @@ -819,13 +863,6 @@ public static function cacheConfigurationProvider(): array
'cacheName' => 'result_cache_driver',
'cacheConfig' => ['type' => null],
],

'metadata_cache_pool' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'doctrine.orm.cache.provider.metadata_cache_pool',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => 'pool', 'pool' => 'metadata_cache_pool'],
],
'query_cache_pool' => [
'expectedAliasName' => 'doctrine.orm.default_query_cache',
'expectedAliasTarget' => 'doctrine.orm.cache.provider.query_cache_pool',
Expand All @@ -838,13 +875,6 @@ public static function cacheConfigurationProvider(): array
'cacheName' => 'result_cache_driver',
'cacheConfig' => ['type' => 'pool', 'pool' => 'result_cache_pool'],
],

'metadata_cache_service' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'service_target_metadata',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
],
'query_cache_service' => [
'expectedAliasName' => 'doctrine.orm.default_query_cache',
'expectedAliasTarget' => 'service_target_query',
Expand Down
1 change: 1 addition & 0 deletions UPGRADE-2.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ Configuration
* `doctrine.dbal.keep_slave`. Use `doctrine.dbal.keep_replica`

Similarly, if you use XML configuration, please replace `<slave>` with `<replica>`.
* The `metadata_cache_driver` configuration key has been deprecated. PHP Array cache is now automatically registered when `%kernel.debug%` is false.