Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b4b00c9

Browse filesBrowse files
jderussefabpot
authored andcommitted
[Lock] Include lock component in framework bundle
1 parent 084e49f commit b4b00c9
Copy full SHA for b4b00c9

File tree

18 files changed

+618
-5
lines changed
Filter options

18 files changed

+618
-5
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1919
use Symfony\Component\Config\Definition\ConfigurationInterface;
2020
use Symfony\Component\Form\Form;
21+
use Symfony\Component\Lock\Lock;
22+
use Symfony\Component\Lock\Store\SemaphoreStore;
2123
use Symfony\Component\Serializer\Serializer;
2224
use Symfony\Component\Translation\Translator;
2325
use Symfony\Component\Validator\Validation;
@@ -129,6 +131,7 @@ public function getConfigTreeBuilder()
129131
$this->addCacheSection($rootNode);
130132
$this->addPhpErrorsSection($rootNode);
131133
$this->addWebLinkSection($rootNode);
134+
$this->addLockSection($rootNode);
132135

133136
return $treeBuilder;
134137
}
@@ -875,6 +878,49 @@ private function addPhpErrorsSection(ArrayNodeDefinition $rootNode)
875878
;
876879
}
877880

881+
private function addLockSection(ArrayNodeDefinition $rootNode)
882+
{
883+
$rootNode
884+
->children()
885+
->arrayNode('lock')
886+
->info('Lock configuration')
887+
->{!class_exists(FullStack::class) && class_exists(Lock::class) ? 'canBeDisabled' : 'canBeEnabled'}()
888+
->beforeNormalization()
889+
->ifString()->then(function ($v) { return array('enabled' => true, 'resources' => $v); })
890+
->end()
891+
->beforeNormalization()
892+
->ifTrue(function ($v) { return is_array($v) && !isset($v['resources']); })
893+
->then(function ($v) {
894+
$e = $v['enabled'];
895+
unset($v['enabled']);
896+
897+
return array('enabled' => $e, 'resources' => $v);
898+
})
899+
->end()
900+
->addDefaultsIfNotSet()
901+
->fixXmlConfig('resource')
902+
->children()
903+
->arrayNode('resources')
904+
->requiresAtLeastOneElement()
905+
->defaultValue(array('default' => array(class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphore' : 'flock')))
906+
->beforeNormalization()
907+
->ifString()->then(function ($v) { return array('default' => $v); })
908+
->end()
909+
->beforeNormalization()
910+
->ifTrue(function ($v) { return is_array($v) && array_keys($v) === range(0, count($v) - 1); })
911+
->then(function ($v) { return array('default' => $v); })
912+
->end()
913+
->prototype('array')
914+
->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
915+
->prototype('scalar')->end()
916+
->end()
917+
->end()
918+
->end()
919+
->end()
920+
->end()
921+
;
922+
}
923+
878924
private function addWebLinkSection(ArrayNodeDefinition $rootNode)
879925
{
880926
$rootNode

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+88Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use Symfony\Component\DependencyInjection\ContainerInterface;
3939
use Symfony\Component\DependencyInjection\Definition;
4040
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
41+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
4142
use Symfony\Component\DependencyInjection\Exception\LogicException;
4243
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
4344
use Symfony\Component\DependencyInjection\Reference;
@@ -54,6 +55,11 @@
5455
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
5556
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
5657
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
58+
use Symfony\Component\Lock\Factory;
59+
use Symfony\Component\Lock\Lock;
60+
use Symfony\Component\Lock\LockInterface;
61+
use Symfony\Component\Lock\Store\StoreFactory;
62+
use Symfony\Component\Lock\StoreInterface;
5763
use Symfony\Component\PropertyAccess\PropertyAccessor;
5864
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
5965
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
@@ -298,6 +304,10 @@ public function load(array $configs, ContainerBuilder $container)
298304
$this->registerPropertyInfoConfiguration($config['property_info'], $container, $loader);
299305
}
300306

307+
if ($this->isConfigEnabled($container, $config['lock'])) {
308+
$this->registerLockConfiguration($config['lock'], $container, $loader);
309+
}
310+
301311
if ($this->isConfigEnabled($container, $config['web_link'])) {
302312
if (!class_exists(HttpHeaderSerializer::class)) {
303313
throw new LogicException('WebLink support cannot be enabled as the WebLink component is not installed.');
@@ -1672,6 +1682,84 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
16721682
}
16731683
}
16741684

1685+
private function registerLockConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
1686+
{
1687+
$loader->load('lock.xml');
1688+
1689+
foreach ($config['resources'] as $resourceName => $resourceStores) {
1690+
if (0 === count($resourceStores)) {
1691+
continue;
1692+
}
1693+
1694+
// Generate stores
1695+
$storeDefinitions = array();
1696+
foreach ($resourceStores as $storeDsn) {
1697+
$storeDsn = $container->resolveEnvPlaceholders($storeDsn, null, $usedEnvs);
1698+
switch (true) {
1699+
case 'flock' === $storeDsn:
1700+
$storeDefinition = new Reference('lock.store.flock');
1701+
break;
1702+
case 'semaphore' === $storeDsn:
1703+
$storeDefinition = new Reference('lock.store.semaphore');
1704+
break;
1705+
case $usedEnvs || preg_match('#^[a-z]++://#', $storeDsn):
1706+
if (!$container->hasDefinition($connectionDefinitionId = $container->hash($storeDsn))) {
1707+
$connectionDefinition = new Definition(\stdClass::class);
1708+
$connectionDefinition->setPublic(false);
1709+
$connectionDefinition->setFactory(array(StoreFactory::class, 'createConnection'));
1710+
$connectionDefinition->setArguments(array($storeDsn));
1711+
$container->setDefinition($connectionDefinitionId, $connectionDefinition);
1712+
}
1713+
1714+
$storeDefinition = new Definition(StoreInterface::class);
1715+
$storeDefinition->setPublic(false);
1716+
$storeDefinition->setFactory(array(StoreFactory::class, 'createStore'));
1717+
$storeDefinition->setArguments(array(new Reference($connectionDefinitionId)));
1718+
1719+
$container->setDefinition($storeDefinitionId = 'lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition);
1720+
1721+
$storeDefinition = new Reference($storeDefinitionId);
1722+
break;
1723+
default:
1724+
throw new InvalidArgumentException(sprintf('Lock store DSN "%s" is not valid in resource "%s"', $storeDsn, $resourceName));
1725+
}
1726+
1727+
$storeDefinitions[] = $storeDefinition;
1728+
}
1729+
1730+
// Wrap array of stores with CombinedStore
1731+
if (count($storeDefinitions) > 1) {
1732+
$combinedDefinition = new ChildDefinition('lock.store.combined.abstract');
1733+
$combinedDefinition->replaceArgument(0, $storeDefinitions);
1734+
$container->setDefinition('lock.'.$resourceName.'.store', $combinedDefinition);
1735+
} else {
1736+
$container->setAlias('lock.'.$resourceName.'.store', new Alias((string) $storeDefinitions[0], false));
1737+
}
1738+
1739+
// Generate factories for each resource
1740+
$factoryDefinition = new ChildDefinition('lock.factory.abstract');
1741+
$factoryDefinition->replaceArgument(0, new Reference('lock.'.$resourceName.'.store'));
1742+
$container->setDefinition('lock.'.$resourceName.'.factory', $factoryDefinition);
1743+
1744+
// Generate services for lock instances
1745+
$lockDefinition = new Definition(Lock::class);
1746+
$lockDefinition->setPublic(false);
1747+
$lockDefinition->setFactory(array(new Reference('lock.'.$resourceName.'.factory'), 'createLock'));
1748+
$lockDefinition->setArguments(array($resourceName));
1749+
$container->setDefinition('lock.'.$resourceName, $lockDefinition);
1750+
1751+
// provide alias for default resource
1752+
if ('default' === $resourceName) {
1753+
$container->setAlias('lock.store', new Alias('lock.'.$resourceName.'.store', false));
1754+
$container->setAlias('lock.factory', new Alias('lock.'.$resourceName.'.factory', false));
1755+
$container->setAlias('lock', new Alias('lock.'.$resourceName, false));
1756+
$container->setAlias(StoreInterface::class, new Alias('lock.store', false));
1757+
$container->setAlias(Factory::class, new Alias('lock.factory', false));
1758+
$container->setAlias(LockInterface::class, new Alias('lock', false));
1759+
}
1760+
}
1761+
}
1762+
16751763
private function registerCacheConfiguration(array $config, ContainerBuilder $container)
16761764
{
16771765
$version = substr(str_replace('/', '-', base64_encode(hash('sha256', uniqid(mt_rand(), true), true))), 0, 22);
+38Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<defaults public="false" />
9+
10+
<service id="lock.store.flock" class="Symfony\Component\Lock\Store\FlockStore" />
11+
12+
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore" />
13+
14+
<service id="lock.store.memcached.abstract" class="Symfony\Component\Lock\Store\MemcachedStore" abstract="true">
15+
<argument /> <!-- Memcached connection service -->
16+
</service>
17+
18+
<service id="lock.store.redis.abstract" class="Symfony\Component\Lock\Store\RedisStore" abstract="true">
19+
<argument /> <!-- Redis connection service -->
20+
</service>
21+
22+
<service id="lock.store.combined.abstract" class="Symfony\Component\Lock\Store\CombinedStore" abstract="true">
23+
<argument /> <!-- List of stores -->
24+
<argument type="service" id="lock.strategy.majority" /> <!-- Strategy -->
25+
</service>
26+
27+
<service id="lock.strategy.majority" class="Symfony\Component\Lock\Strategy\ConsensusStrategy" />
28+
29+
<service id="lock.factory.abstract" class="Symfony\Component\Lock\Factory" abstract="true">
30+
<tag name="monolog.logger" channel="lock" />
31+
<argument /> <!-- Store -->
32+
<call method="setLogger">
33+
<argument type="service" id="logger" on-invalid="ignore" />
34+
</call>
35+
</service>
36+
37+
</services>
38+
</container>

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<xsd:element name="property-info" type="property_info" minOccurs="0" maxOccurs="1" />
3030
<xsd:element name="cache" type="cache" minOccurs="0" maxOccurs="1" />
3131
<xsd:element name="workflow" type="workflow" minOccurs="0" maxOccurs="unbounded" />
32+
<xsd:element name="lock" type="lock" minOccurs="0" maxOccurs="1" />
3233
</xsd:choice>
3334

3435
<xsd:attribute name="http-method-override" type="xsd:boolean" />
@@ -296,4 +297,19 @@
296297
<xsd:enumeration value="workflow" />
297298
</xsd:restriction>
298299
</xsd:simpleType>
300+
301+
<xsd:complexType name="lock">
302+
<xsd:sequence>
303+
<xsd:element name="resource" type="lock_resource" minOccurs="1" maxOccurs="unbounded" />
304+
</xsd:sequence>
305+
<xsd:attribute name="enabled" type="xsd:boolean" />
306+
</xsd:complexType>
307+
308+
<xsd:complexType name="lock_resource">
309+
<xsd:simpleContent>
310+
<xsd:extension base="xsd:string">
311+
<xsd:attribute name="name" type="xsd:string" />
312+
</xsd:extension>
313+
</xsd:simpleContent>
314+
</xsd:complexType>
299315
</xsd:schema>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Bundle\FullStack;
1717
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1818
use Symfony\Component\Config\Definition\Processor;
19+
use Symfony\Component\Lock\Store\SemaphoreStore;
1920

2021
class ConfigurationTest extends TestCase
2122
{
@@ -343,6 +344,14 @@ protected static function getBundleDefaultConfig()
343344
'web_link' => array(
344345
'enabled' => !class_exists(FullStack::class),
345346
),
347+
'lock' => array(
348+
'enabled' => !class_exists(FullStack::class),
349+
'resources' => array(
350+
'default' => array(
351+
class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphore' : 'flock',
352+
),
353+
),
354+
),
346355
);
347356
}
348357
}
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config>
9+
<framework:lock/>
10+
</framework:config>
11+
</container>
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
9+
<parameters>
10+
<parameter key="env(REDIS_URL)">redis://paas.com</parameter>
11+
</parameters>
12+
13+
<framework:config>
14+
<framework:lock>
15+
<framework:resource name="foo">semaphore</framework:resource>
16+
<framework:resource name="bar">flock</framework:resource>
17+
<framework:resource name="baz">semaphore</framework:resource>
18+
<framework:resource name="baz">flock</framework:resource>
19+
<framework:resource name="qux">%env(REDIS_URL)%</framework:resource>
20+
</framework:lock>
21+
</framework:config>
22+
</container>
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
framework:
2+
lock: ~
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
parameters:
2+
env(REDIS_DSN): redis://paas.com
3+
4+
framework:
5+
lock:
6+
foo: semaphore
7+
bar: flock
8+
baz: [semaphore, flock]
9+
qux: "%env(REDIS_DSN)%"

‎src/Symfony/Bundle/FrameworkBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/composer.json
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"symfony/workflow": "~3.3|~4.0",
5555
"symfony/yaml": "~3.2|~4.0",
5656
"symfony/property-info": "~3.3|~4.0",
57+
"symfony/lock": "~3.4|~4.0",
5758
"symfony/web-link": "~3.3|~4.0",
5859
"doctrine/annotations": "~1.0",
5960
"phpdocumentor/reflection-docblock": "^3.0|^4.0",

‎src/Symfony/Component/Console/Command/LockableTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Command/LockableTrait.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private function lock($name = null, $blocking = false)
4646
if (SemaphoreStore::isSupported($blocking)) {
4747
$store = new SemaphoreStore();
4848
} else {
49-
$store = new FlockStore(sys_get_temp_dir());
49+
$store = new FlockStore();
5050
}
5151

5252
$this->lock = (new Factory($store))->createLock($name ?: $this->getName());

‎src/Symfony/Component/Console/Tests/Command/LockableTraitTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/Command/LockableTraitTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function testLockReturnsFalseIfAlreadyLockedByAnotherCommand()
4444
if (SemaphoreStore::isSupported(false)) {
4545
$store = new SemaphoreStore();
4646
} else {
47-
$store = new FlockStore(sys_get_temp_dir());
47+
$store = new FlockStore();
4848
}
4949

5050
$lock = (new Factory($store))->createLock($command->getName());

‎src/Symfony/Component/Lock/Store/FlockStore.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Store/FlockStore.php
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ class FlockStore implements StoreInterface
3232
private $lockPath;
3333

3434
/**
35-
* @param string $lockPath the directory to store the lock
35+
* @param string|null $lockPath the directory to store the lock, defaults to the system's temporary directory
3636
*
3737
* @throws LockStorageException If the lock directory could not be created or is not writable
3838
*/
39-
public function __construct($lockPath)
39+
public function __construct($lockPath = null)
4040
{
41+
if (null === $lockPath) {
42+
$lockPath = sys_get_temp_dir();
43+
}
4144
if (!is_dir($lockPath) || !is_writable($lockPath)) {
4245
throw new InvalidArgumentException(sprintf('The directory "%s" is not writable.', $lockPath));
4346
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.