|
15 | 15 | use Symfony\Bridge\Monolog\Processor\DebugProcessor;
|
16 | 16 | use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
17 | 17 | use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
| 18 | +use Symfony\Component\Cache\Adapter\AbstractAdapter; |
18 | 19 | use Symfony\Component\Cache\Adapter\AdapterInterface;
|
19 | 20 | use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
20 | 21 | use Symfony\Component\Config\FileLocator;
|
|
28 | 29 | use Symfony\Component\DependencyInjection\ContainerBuilder;
|
29 | 30 | use Symfony\Component\DependencyInjection\ContainerInterface;
|
30 | 31 | use Symfony\Component\DependencyInjection\Definition;
|
| 32 | +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
31 | 33 | use Symfony\Component\DependencyInjection\Exception\LogicException;
|
32 | 34 | use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
33 | 35 | use Symfony\Component\DependencyInjection\Reference;
|
|
41 | 43 | use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
42 | 44 | use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
43 | 45 | use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
| 46 | +use Symfony\Component\Lock\Lock; |
| 47 | +use Symfony\Component\Lock\Store\MemcachedStore; |
| 48 | +use Symfony\Component\Lock\Store\RedisStore; |
| 49 | +use Symfony\Component\Lock\Store\StoreFactory; |
44 | 50 | use Symfony\Component\PropertyAccess\PropertyAccessor;
|
45 | 51 | use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
|
46 | 52 | use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
|
@@ -1410,69 +1416,75 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
|
1410 | 1416 |
|
1411 | 1417 | $container->getDefinition('lock.store.flock')->replaceArgument(0, sys_get_temp_dir());
|
1412 | 1418 |
|
1413 |
| - // configure connectable stores |
1414 |
| - foreach (array('redis', 'memcached') as $store) { |
1415 |
| - if ($this->isConfigEnabled($container, $config[$store]) && count($config[$store]['hosts']) > 0) { |
1416 |
| - /** @var Reference[] $hostsDefinitions */ |
1417 |
| - $hostsDefinitions = array(); |
1418 |
| - foreach ($config[$store]['hosts'] as $host) { |
1419 |
| - $definition = new ChildDefinition('lock.store.'.$store.'.abstract'); |
1420 |
| - |
1421 |
| - // generate a service connection for the host |
1422 |
| - $container->resolveEnvPlaceholders($host, null, $usedEnvs); |
1423 |
| - if ($usedEnvs || preg_match('#^[a-z]++://#', $host)) { |
1424 |
| - $dsn = $host; |
| 1419 | + foreach ($config['resources'] as $resourceName => $resourceStores) { |
| 1420 | + if (0 === count($resourceStores)) { |
| 1421 | + continue; |
| 1422 | + } |
1425 | 1423 |
|
1426 |
| - if (!$container->hasDefinition($host = 'lock.connection.'.$store.'.'.md5($dsn))) { |
| 1424 | + // Generate stores |
| 1425 | + $storeDefinitions = array(); |
| 1426 | + foreach ($resourceStores as $storeDsn) { |
| 1427 | + $storeDsn = $container->resolveEnvPlaceholders($storeDsn, null, $usedEnvs); |
| 1428 | + switch (true) { |
| 1429 | + case 'flock' === $storeDsn: |
| 1430 | + $storeDefinition = new Reference('lock.store.flock'); |
| 1431 | + break; |
| 1432 | + case 'semaphore' === $storeDsn: |
| 1433 | + $storeDefinition = new Reference('lock.store.semaphore'); |
| 1434 | + break; |
| 1435 | + case $usedEnvs || preg_match('#^[a-z]++://#', $storeDsn): |
| 1436 | + if (!$container->hasDefinition($connectionDefinitionId = md5($storeDsn))) { |
1427 | 1437 | $connectionDefinition = new Definition(\stdClass::class);
|
1428 |
| - $connectionDefinition->setPublic(false); |
1429 |
| - $connectionDefinition->setFactory(array($container->getDefinition($definition->getParent())->getClass(), 'createConnection')); |
1430 |
| - $connectionDefinition->setArguments(array($dsn)); |
1431 |
| - $container->setDefinition($host, $connectionDefinition); |
| 1438 | + $connectionDefinition ->setPublic(false); |
| 1439 | + $connectionDefinition ->setFactory(array(StoreFactory::class, 'createConnection')); |
| 1440 | + $connectionDefinition ->setArguments(array($storeDsn)); |
| 1441 | + $container->setDefinition($connectionDefinitionId, $connectionDefinition ); |
1432 | 1442 | }
|
1433 |
| - } |
1434 | 1443 |
|
1435 |
| - $definition->replaceArgument(0, new Reference($host)); |
1436 |
| - $container->setDefinition($name = 'lock.store.'.$store.'.'.md5($host), $definition); |
| 1444 | + $storeDefinition = new Definition(\stdClass::class); |
| 1445 | + $storeDefinition->setFactory(array(StoreFactory::class, 'createStore')); |
| 1446 | + $storeDefinition->setArguments(array(new Reference($connectionDefinitionId))); |
1437 | 1447 |
|
1438 |
| - $hostsDefinitions[] = new Reference($name); |
1439 |
| - } |
| 1448 | + $container->setDefinition($storeDefinitionId = 'lock.'.$resourceName.'.store.'.md5($storeDsn), $storeDefinition); |
| 1449 | + |
| 1450 | + $storeDefinition = new Reference($storeDefinitionId); |
| 1451 | + break; |
| 1452 | + case $usedEnvs: |
1440 | 1453 |
|
1441 |
| - if (count($hostsDefinitions) > 1) { |
1442 |
| - $definition = new ChildDefinition('lock.store.combined.abstract'); |
1443 |
| - $definition->replaceArgument(0, $hostsDefinitions); |
1444 |
| - $container->setDefinition('lock.store.'.$store, $definition); |
1445 |
| - } else { |
1446 |
| - $container->setAlias('lock.store.'.$store, new Alias((string) $hostsDefinitions[0])); |
| 1454 | + break; |
| 1455 | + default: |
| 1456 | + throw new InvalidArgumentException(sprintf('Lock store DSN "%s" is not valid in resource "%s"', $storeDsn, $resourceName)); |
1447 | 1457 | }
|
1448 |
| - } |
1449 |
| - } |
1450 | 1458 |
|
1451 |
| - // wrap non blocking store with retry mechanism |
1452 |
| - foreach (array('redis', 'memcached') as $store) { |
1453 |
| - if ($container->has($name = 'lock.store.'.$store)) { |
1454 |
| - $container->register($name.'.retry', 'Symfony\\Component\\Lock\\Store\\RetryTillSaveStore') |
1455 |
| - ->setDecoratedService($name) |
1456 |
| - ->addArgument(new Reference($name.'.retry.inner')) |
1457 |
| - ->setPublic(false) |
1458 |
| - ; |
| 1459 | + $storeDefinitions[] = $storeDefinition; |
1459 | 1460 | }
|
1460 |
| - } |
1461 | 1461 |
|
1462 |
| - // generate factory for activated stores |
1463 |
| - $hasAlias = false; |
1464 |
| - // Order of stores matters: First enabled will be used in the default "lock.factory" |
1465 |
| - foreach (array('redis', 'memcached', 'semaphore', 'flock') as $store) { |
1466 |
| - if ($this->isConfigEnabled($container, $config[$store]) && $container->has('lock.store.'.$store)) { |
1467 |
| - $definition = new ChildDefinition('lock.factory.abstract'); |
1468 |
| - $definition->replaceArgument(0, new Reference('lock.store.'.$store)); |
1469 |
| - $definition->setPublic(true); |
1470 |
| - $container->setDefinition('lock.factory.'.$store, $definition); |
| 1462 | + // Wrap array of stores with CombinedStore |
| 1463 | + if (count($storeDefinitions) > 1) { |
| 1464 | + $combinedDefinition = new ChildDefinition('lock.store.combined.abstract'); |
| 1465 | + $combinedDefinition->replaceArgument(0, $storeDefinitions); |
| 1466 | + $container->setDefinition('lock.'.$resourceName.'.store', $combinedDefinition); |
| 1467 | + } else { |
| 1468 | + $container->setAlias('lock.'.$resourceName.'.store', new Alias((string) $storeDefinitions[0])); |
| 1469 | + } |
1471 | 1470 |
|
1472 |
| - if (!$hasAlias) { |
1473 |
| - $container->setAlias('lock.factory', new Alias('lock.factory.'.$store)); |
1474 |
| - $hasAlias = true; |
1475 |
| - } |
| 1471 | + // Generate factories for each resource |
| 1472 | + $factoryDefinition = new ChildDefinition('lock.factory.abstract'); |
| 1473 | + $factoryDefinition->replaceArgument(0, new Reference('lock.'.$resourceName.'.store')); |
| 1474 | + $factoryDefinition->setPublic(true); |
| 1475 | + $container->setDefinition('lock.'.$resourceName.'.factory', $factoryDefinition); |
| 1476 | + |
| 1477 | + // Generate services for lock instances |
| 1478 | + $lockDefinition = new Definition(Lock::class); |
| 1479 | + $lockDefinition->setFactory(array(new Reference('lock.'.$resourceName.'.factory'), 'createLock')); |
| 1480 | + $lockDefinition->setArguments(array($resourceName)); |
| 1481 | + $container->setDefinition('lock.'.$resourceName, $lockDefinition); |
| 1482 | + |
| 1483 | + // provide alias for default resource |
| 1484 | + if ('default' === $resourceName) { |
| 1485 | + $container->setAlias('lock.store', new Alias('lock.'.$resourceName.'.store')); |
| 1486 | + $container->setAlias('lock.factory', new Alias('lock.'.$resourceName.'.factory')); |
| 1487 | + $container->setAlias('lock', new Alias('lock.'.$resourceName)); |
1476 | 1488 | }
|
1477 | 1489 | }
|
1478 | 1490 | }
|
|
0 commit comments