Skip to content

Commit

Permalink
Merge pull request #948 from alcaeus/add-symfony-cache-pool-support
Browse files Browse the repository at this point in the history
Add symfony cache pool support
  • Loading branch information
alcaeus committed Apr 7, 2019
2 parents eb88c42 + 92dfa1f commit 8af32bd
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 39 deletions.
15 changes: 13 additions & 2 deletions DependencyInjection/Configuration.php
Expand Up @@ -9,6 +9,8 @@
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use function array_key_exists;
use function is_array;

/**
* This class contains the configuration information for the bundle
Expand Down Expand Up @@ -687,18 +689,27 @@ private function getOrmCacheDriverNode($name)
->addDefaultsIfNotSet()
->beforeNormalization()
->ifString()
->then(static function ($v) {
->then(static function ($v) : array {
return ['type' => $v];
})
->end()
->beforeNormalization()
->ifTrue(static function ($v) : bool {
return is_array($v) && array_key_exists('cache_provider', $v);
})
->then(static function ($v) : array {
return ['type' => 'provider'] + $v;
})
->end()
->children()
->scalarNode('type')->defaultValue('array')->end()
->scalarNode('id')->end()
->scalarNode('pool')->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('database')->end()
->scalarNode('instance_class')->end()
->scalarNode('class')->end()
->scalarNode('id')->end()
->scalarNode('namespace')->defaultNull()->end()
->scalarNode('cache_provider')->defaultNull()->end()
->end();
Expand Down
38 changes: 35 additions & 3 deletions DependencyInjection/DoctrineExtension.php
Expand Up @@ -14,6 +14,7 @@
use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware;
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
use Symfony\Bridge\Doctrine\Validator\DoctrineLoader;
use Symfony\Component\Cache\DoctrineProvider;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
Expand All @@ -25,6 +26,8 @@
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory;
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
use function class_exists;
use function sprintf;

/**
* DoctrineExtension is an extension for the Doctrine DBAL and ORM library.
Expand Down Expand Up @@ -715,10 +718,24 @@ protected function getMappingResourceExtension()
*/
protected function loadCacheDriver($driverName, $entityManagerName, array $driverMap, ContainerBuilder $container)
{
if (! empty($driverMap['cache_provider'])) {
$aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $entityManagerName, $driverName));
$serviceId = sprintf('doctrine_cache.providers.%s', $driverMap['cache_provider']);
$serviceId = null;
$aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $entityManagerName, $driverName));

switch ($driverMap['type']) {
case 'service':
$serviceId = $driverMap['id'];
break;

case 'pool':
$serviceId = $this->createPoolCacheDefinition($container, $aliasId, $driverMap['pool']);
break;

case 'provider':
$serviceId = sprintf('doctrine_cache.providers.%s', $driverMap['cache_provider']);
break;
}

if ($serviceId !== null) {
$container->setAlias($aliasId, new Alias($serviceId, false));

return $aliasId;
Expand Down Expand Up @@ -832,4 +849,19 @@ private function loadMessengerServices(ContainerBuilder $container) : void
$transportFactoryDefinition = $container->getDefinition('messenger.transport.doctrine.factory');
$transportFactoryDefinition->addTag('messenger.transport_factory');
}

private function createPoolCacheDefinition(ContainerBuilder $container, string $aliasId, string $poolName) : string
{
if (! class_exists(DoctrineProvider::class)) {
throw new LogicException('Using the "pool" cache type is only supported when symfony/cache is installed.');
}

$serviceId = sprintf('doctrine.orm.cache.pool.%s', $poolName);

$definition = $container->register($aliasId, DoctrineProvider::class);
$definition->addArgument(new Reference($poolName));
$definition->setPrivate(true);

return $serviceId;
}
}
58 changes: 40 additions & 18 deletions Resources/doc/configuration.rst
Expand Up @@ -273,29 +273,32 @@ Configuration Reference
some_em:
query_cache_driver:
type: array
id: ~
pool: ~
host: ~
port: ~
instance_class: ~
class: ~
id: ~
namespace: ~
cache_provider: ~
metadata_cache_driver:
type: array
id: ~
pool: ~
host: ~
port: ~
instance_class: ~
class: ~
id: ~
namespace: ~
cache_provider: ~
result_cache_driver:
type: array
id: ~
pool: ~
host: ~
port: ~
instance_class: ~
class: ~
id: ~
namespace: ~
cache_provider: ~
entity_listeners:
Expand Down Expand Up @@ -323,11 +326,12 @@ Configuration Reference
second_level_cache:
region_cache_driver:
type: array
pool: ~
id: ~
host: ~
port: ~
instance_class: ~
class: ~
id: ~
namespace: ~
cache_provider: ~
region_lock_lifetime: 60
Expand All @@ -341,11 +345,12 @@ Configuration Reference
name:
cache_driver:
type: array
id: ~
pool: ~
host: ~
port: ~
instance_class: ~
class: ~
id: ~
namespace: ~
cache_provider: ~
lock_path: '%kernel.cache_dir%/doctrine/orm/slc/filelock'
Expand Down Expand Up @@ -621,33 +626,36 @@ Configuration Reference
<doctrine:query-cache-driver
type="array"
id=""
pool=""
host=""
port=""
instance-class=""
class=""
id=""
namespace="null"
cache-provider="null"
/>
<doctrine:metadata-cache-driver
type="memcache"
id=""
pool=""
host="localhost"
port="11211"
instance-class="Memcache"
class="Doctrine\Common\Cache\MemcacheCache"
id=""
namespace="null"
cache-provider="null"
/>
<doctrine:result-cache-driver
type="array"
id=""
pool=""
host=""
port=""
instance-class=""
class=""
id=""
namespace="null"
cache-provider="null"
/>
Expand Down Expand Up @@ -682,11 +690,12 @@ Configuration Reference
<doctrine:region-cache-driver
type="array"
id=""
pool=""
host=""
port=""
instance-class=""
class=""
id=""
namespace="null"
cache-provider="null"
/>
Expand All @@ -703,11 +712,12 @@ Configuration Reference
<doctrine:cache-driver
type="array"
id=""
pool=""
host=""
port=""
instance-class=""
class=""
id=""
namespace="null"
cache-provider="null"
/>
Expand Down Expand Up @@ -825,8 +835,11 @@ The environment variables that doctrine is going to change in the Oracle DB sess
Caching Drivers
~~~~~~~~~~~~~~~

For the caching drivers you can specify the values ``array``, ``apc``, ``apcu``, ``memcache``,
``memcached`` or ``xcache``.
For the caching drivers you can specify the values ``array``, ``apc``, ``apcu``,
``memcache``, ``memcached``, ``redis``, ``wincache``, ``zenddata`` and
``xcache``. You can use a Symfony Cache pool by using the ``pool`` type and
creating a cache bool through the FrameworkBundle configuration. The ``service``
type lets you define the ``ID`` of your own caching service.

The following example shows an overview of the caching configurations:

Expand All @@ -835,13 +848,22 @@ The following example shows an overview of the caching configurations:
doctrine:
orm:
auto_mapping: true
metadata_cache_driver: apcu
query_cache_driver: xcache
# each caching driver type defines its own config options
metadata_cache_driver: apc
# the 'pool' type requires to define the 'pool' option and configure a cache pool using the FrameworkBundle
result_cache_driver:
type: memcache
host: localhost
port: 11211
instance_class: Memcache
type: pool
pool: doctrine.result_cache_pool
# the 'service' type requires to define the 'id' option too
query_cache_driver:
type: service
id: App\ORM\MyCacheService
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
Mapping Configuration
~~~~~~~~~~~~~~~~~~~~~
Expand Down
87 changes: 71 additions & 16 deletions Tests/DependencyInjection/DoctrineExtensionTest.php
Expand Up @@ -665,33 +665,88 @@ public function testMessengerIntegration()
$this->assertCount(1, $middlewarePrototype->getArguments());
}

public function testCacheConfiguration()
/**
* @param array|string $cacheConfig
*
* @dataProvider cacheConfigurationProvider
*/
public function testCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, $cacheConfig) : void
{
$container = $this->getContainer();
$extension = new DoctrineExtension();

$config = BundleConfigurationBuilder::createBuilder()
->addBaseConnection()
->addEntityManager([
'metadata_cache_driver' => ['cache_provider' => 'metadata_cache'],
'query_cache_driver' => ['cache_provider' => 'query_cache'],
'result_cache_driver' => ['cache_provider' => 'result_cache'],
])
->addBaseConnection()
->addEntityManager([$cacheName => $cacheConfig])
->build();

$extension->load([$config], $container);

$this->assertTrue($container->hasAlias('doctrine.orm.default_metadata_cache'));
$alias = $container->getAlias('doctrine.orm.default_metadata_cache');
$this->assertEquals('doctrine_cache.providers.metadata_cache', (string) $alias);
$this->assertTrue($container->hasAlias($expectedAliasName));
$alias = $container->getAlias($expectedAliasName);
$this->assertEquals($expectedAliasTarget, (string) $alias);
}

public static function cacheConfigurationProvider() : array
{
return [
'metadata_cache_provider' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'doctrine_cache.providers.metadata_cache',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['cache_provider' => 'metadata_cache'],
],
'query_cache_provider' => [
'expectedAliasName' => 'doctrine.orm.default_query_cache',
'expectedAliasTarget' => 'doctrine_cache.providers.query_cache',
'cacheName' => 'query_cache_driver',
'cacheConfig' => ['cache_provider' => 'query_cache'],
],
'result_cache_provider' => [
'expectedAliasName' => 'doctrine.orm.default_result_cache',
'expectedAliasTarget' => 'doctrine_cache.providers.result_cache',
'cacheName' => 'result_cache_driver',
'cacheConfig' => ['cache_provider' => 'result_cache'],
],

$this->assertTrue($container->hasAlias('doctrine.orm.default_query_cache'));
$alias = $container->getAlias('doctrine.orm.default_query_cache');
$this->assertEquals('doctrine_cache.providers.query_cache', (string) $alias);
'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',
'cacheName' => 'query_cache_driver',
'cacheConfig' => ['type' => 'service', 'id' => 'service_target_query'],
],
'result_cache_service' => [
'expectedAliasName' => 'doctrine.orm.default_result_cache',
'expectedAliasTarget' => 'service_target_result',
'cacheName' => 'result_cache_driver',
'cacheConfig' => ['type' => 'service', 'id' => 'service_target_result'],
],

$this->assertTrue($container->hasAlias('doctrine.orm.default_result_cache'));
$alias = $container->getAlias('doctrine.orm.default_result_cache');
$this->assertEquals('doctrine_cache.providers.result_cache', (string) $alias);
'metadata_cache_array' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_metadata_cache',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => 'array',
],
'query_cache_array' => [
'expectedAliasName' => 'doctrine.orm.default_query_cache',
'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_query_cache',
'cacheName' => 'query_cache_driver',
'cacheConfig' => 'array',
],
'result_cache_array' => [
'expectedAliasName' => 'doctrine.orm.default_result_cache',
'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_result_cache',
'cacheName' => 'result_cache_driver',
'cacheConfig' => 'array',
],
];
}

public function testShardManager()
Expand Down
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -36,6 +36,7 @@
},
"require-dev": {
"doctrine/orm": "^2.6",
"symfony/cache": "^3.4|^4.1",
"symfony/yaml": "^3.4|^4.1",
"symfony/validator": "^3.4|^4.1",
"symfony/property-info": "^3.4|^4.1",
Expand Down

0 comments on commit 8af32bd

Please sign in to comment.