Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f00128e

Browse files
committed
[Lock] Split "StoreInterface" into multiple interfaces with less responsability
1 parent 80e28a0 commit f00128e

25 files changed

+657
-63
lines changed

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
use Symfony\Component\Lock\Factory;
7171
use Symfony\Component\Lock\Lock;
7272
use Symfony\Component\Lock\LockInterface;
73+
use Symfony\Component\Lock\PersistStoreInterface;
7374
use Symfony\Component\Lock\Store\FlockStore;
7475
use Symfony\Component\Lock\Store\StoreFactory;
7576
use Symfony\Component\Lock\StoreInterface;
@@ -1564,18 +1565,18 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
15641565
$storeDsn = $container->resolveEnvPlaceholders($storeDsn, null, $usedEnvs);
15651566
switch (true) {
15661567
case 'flock' === $storeDsn:
1567-
$storeDefinition = new Reference('lock.store.flock');
1568+
$storeDefinition = new Reference('lock.store_persist.flock');
15681569
break;
15691570
case 0 === strpos($storeDsn, 'flock://'):
15701571
$flockPath = substr($storeDsn, 8);
15711572

1572-
$storeDefinitionId = '.lock.flock.store.'.$container->hash($storeDsn);
1573+
$storeDefinitionId = '.lock.flock.store_persist.'.$container->hash($storeDsn);
15731574
$container->register($storeDefinitionId, FlockStore::class)->addArgument($flockPath);
1574-
15751575
$storeDefinition = new Reference($storeDefinitionId);
1576+
15761577
break;
15771578
case 'semaphore' === $storeDsn:
1578-
$storeDefinition = new Reference('lock.store.semaphore');
1579+
$storeDefinition = new Reference('lock.store_persist.semaphore');
15791580
break;
15801581
case $usedEnvs || preg_match('#^[a-z]++://#', $storeDsn):
15811582
if (!$container->hasDefinition($connectionDefinitionId = '.lock_connection.'.$container->hash($storeDsn))) {
@@ -1591,9 +1592,10 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
15911592
$storeDefinition->setFactory([StoreFactory::class, 'createStore']);
15921593
$storeDefinition->setArguments([new Reference($connectionDefinitionId)]);
15931594

1594-
$container->setDefinition($storeDefinitionId = '.lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition);
1595+
$container->setDefinition($legacyStoreDefinitionId = 'lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition)->setDeprecated(true, 'The "%service_id%" service is deprecated.');
1596+
$container->setDefinition($storeDefinitionId = 'lock.'.$resourceName.'.persist_store.'.$container->hash($storeDsn), $storeDefinition);
15951597

1596-
$storeDefinition = new Reference($storeDefinitionId);
1598+
$storeDefinition = new Reference($legacyStoreDefinitionId);
15971599
break;
15981600
default:
15991601
throw new InvalidArgumentException(sprintf('Lock store DSN "%s" is not valid in resource "%s"', $storeDsn, $resourceName));
@@ -1606,6 +1608,8 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
16061608
if (\count($storeDefinitions) > 1) {
16071609
$combinedDefinition = new ChildDefinition('lock.store.combined.abstract');
16081610
$combinedDefinition->replaceArgument(0, $storeDefinitions);
1611+
1612+
$container->setDefinition('lock.'.$resourceName.'.persist_store', $combinedDefinition);
16091613
$container->setDefinition('lock.'.$resourceName.'.store', $combinedDefinition);
16101614
} else {
16111615
$container->setAlias('lock.'.$resourceName.'.store', new Alias((string) $storeDefinitions[0], false));
@@ -1628,11 +1632,14 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
16281632
$container->setAlias('lock.store', new Alias('lock.'.$resourceName.'.store', false));
16291633
$container->setAlias('lock.factory', new Alias('lock.'.$resourceName.'.factory', false));
16301634
$container->setAlias('lock', new Alias('lock.'.$resourceName, false));
1631-
$container->setAlias(StoreInterface::class, new Alias('lock.store', false));
1635+
$container->setAlias(StoreInterface::class, new Alias('lock.store', false))->setDeprecated(true, 'The "%alias_id%" service is deprecated.');
1636+
$container->setAlias(PersistStoreInterface::class, new Alias('lock.persist_store', false));
1637+
16321638
$container->setAlias(Factory::class, new Alias('lock.factory', false));
16331639
$container->setAlias(LockInterface::class, new Alias('lock', false));
16341640
} else {
1635-
$container->registerAliasForArgument('lock.'.$resourceName.'.store', StoreInterface::class, $resourceName.'.lock.store');
1641+
$container->setAlias(PersistStoreInterface::class, new Alias('lock.persist_store', false));
1642+
$container->registerAliasForArgument('lock.'.$resourceName.'.store', StoreInterface::class, $resourceName.'.lock.store')->setDeprecated(true, 'The "%alias_id%" service is deprecated.');
16361643
$container->registerAliasForArgument('lock.'.$resourceName.'.factory', Factory::class, $resourceName.'.lock.factory');
16371644
$container->registerAliasForArgument('lock.'.$resourceName, LockInterface::class, $resourceName.'.lock');
16381645
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/lock.xml

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,49 @@
77
<services>
88
<defaults public="false" />
99

10-
<service id="lock.store.flock" class="Symfony\Component\Lock\Store\FlockStore" />
10+
<service id="lock.store.flock" class="Symfony\Component\Lock\Store\FlockStore" >
11+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 use "lock.store_persist.flock" instead.</deprecated>
12+
</service>
13+
<service id="lock.store_persist.flock" class="Symfony\Component\Lock\Store\FlockStore" />
1114

12-
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore" />
15+
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore" >
16+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 use "lock.store_persist.semaphore" instead.</deprecated>
17+
</service>
18+
<service id="lock.store_persist.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore" />
19+
<service id="lock.store_persist.memcached.abstract" class="Symfony\Component\Lock\Store\MemcachedStore" abstract="true">
20+
<argument /> <!-- Memcached connection service -->
21+
</service>
22+
23+
<service id="lock.store_persist.redis.abstract" class="Symfony\Component\Lock\Store\RedisStore" abstract="true">
24+
<argument /> <!-- Redis connection service -->
25+
</service>
26+
<service id="lock.store_persist.combined.abstract" class="Symfony\Component\Lock\Store\CombinedStore" abstract="true">
27+
<argument /> <!-- List of stores -->
28+
<argument type="service" id="lock.strategy.majority" /> <!-- Strategy -->
29+
</service>
1330

1431
<service id="lock.store.memcached.abstract" class="Symfony\Component\Lock\Store\MemcachedStore" abstract="true">
32+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 use "lock.store_persist.memcached.abstract" instead.</deprecated>
1533
<argument /> <!-- Memcached connection service -->
1634
</service>
1735

1836
<service id="lock.store.redis.abstract" class="Symfony\Component\Lock\Store\RedisStore" abstract="true">
37+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 use "lock.store_persist.redis.abstract" instead.</deprecated>
1938
<argument /> <!-- Redis connection service -->
2039
</service>
2140

2241
<service id="lock.store.combined.abstract" class="Symfony\Component\Lock\Store\CombinedStore" abstract="true">
42+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 use "lock.store_persist.combined.abstract" instead.</deprecated>
2343
<argument /> <!-- List of stores -->
2444
<argument type="service" id="lock.strategy.majority" /> <!-- Strategy -->
2545
</service>
2646

47+
<service id="lock.store.legacy.abstract" class="Symfony\Component\Lock\Store\LegacyStore" abstract="true">
48+
<argument /> <!-- List of stores -->
49+
<argument type="service" id="lock.strategy.majority" /> <!-- Strategy -->
50+
</service>
51+
52+
2753
<service id="lock.strategy.majority" class="Symfony\Component\Lock\Strategy\ConsensusStrategy" />
2854

2955
<service id="lock.factory.abstract" class="Symfony\Component\Lock\Factory" abstract="true">

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ protected function tearDown()
4040
$this->fs->remove($this->kernel->getProjectDir());
4141
}
4242

43+
/**
44+
* @group legacy
45+
* @expectedDeprecation "Symfony\Component\Lock\StoreInterface" is deprecated since Symfony 4.4 and has been splitted into "Symfony\Component\Lock\PersistStoreInterface", "Symfony\Component\Lock\ExpiringStoreInterface", "Symfony\Component\Lock\BlockingStoreInterface".
46+
*/
4347
public function testCacheIsFreshAfterCacheClearedWithWarmup()
4448
{
4549
$input = new ArrayInput(['cache:clear']);

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSessionDomainConstraintPassTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
class AddSessionDomainConstraintPassTest extends TestCase
2222
{
23+
/**
24+
* @group legacy
25+
* @expectedDeprecation "Symfony\Component\Lock\StoreInterface" is deprecated since Symfony 4.4 and has been splitted into "Symfony\Component\Lock\PersistStoreInterface", "Symfony\Component\Lock\ExpiringStoreInterface", "Symfony\Component\Lock\BlockingStoreInterface".
26+
*/
2327
public function testSessionCookie()
2428
{
2529
$container = $this->createContainer(['cookie_domain' => '.symfony.com.', 'cookie_secure' => true]);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public static function setUpBeforeClass()
2828
require_once self::$fixturesPath.'/FooLock2Command.php';
2929
}
3030

31+
/**
32+
* @group legacy
33+
* @expectedDeprecation "Symfony\Component\Lock\StoreInterface" is deprecated since Symfony 4.4 and has been splitted into "Symfony\Component\Lock\PersistStoreInterface", "Symfony\Component\Lock\ExpiringStoreInterface", "Symfony\Component\Lock\BlockingStoreInterface".
34+
*/
3135
public function testLockIsReleased()
3236
{
3337
$command = new \FooLockCommand();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock;
13+
14+
use Symfony\Component\Lock\Exception\LockConflictedException;
15+
use Symfony\Component\Lock\Exception\NotSupportedException;
16+
17+
/**
18+
* BlockingStoreInterface defines an interface to manipulate a lock store.
19+
*
20+
* @author Hamza Amrouche <[email protected]>
21+
*/
22+
interface BlockingStoreInterface
23+
{
24+
/**
25+
* Waits until a key becomes free, then stores the resource.
26+
*
27+
* If the store does not support this feature it should throw a NotSupportedException.
28+
*
29+
* @throws LockConflictedException
30+
* @throws NotSupportedException
31+
*/
32+
public function waitAndSave(Key $key);
33+
34+
/**
35+
* Check if the store can wait until a key becomes free before storing the resource.
36+
*/
37+
public function supportsWaitAndSave(): bool;
38+
}

src/Symfony/Component/Lock/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
4.4.0
5+
-----
6+
7+
* deprecated `Symfony\Component\Lock\StoreInterface` in favor of `Symfony\Component\Lock\BlockingStoreInterface`, `Symfony\Component\Lock\ExpiringStoreInterface`
8+
and `Symfony\Component\Lock\ExpiringStoreInterface`
9+
410
4.2.0
511
-----
612

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock;
13+
14+
use Symfony\Component\Lock\Exception\LockConflictedException;
15+
use Symfony\Component\Lock\Exception\NotSupportedException;
16+
17+
/**
18+
* ExpiringStoreInterface defines an interface to manipulate a lock store.
19+
*
20+
* @author Hamza Amrouche <[email protected]>
21+
*/
22+
interface ExpiringStoreInterface
23+
{
24+
/**
25+
* Extends the ttl of a resource.
26+
*
27+
* If the store does not support this feature it should throw a NotSupportedException.
28+
*
29+
* @param float $ttl amount of seconds to keep the lock in the store
30+
*
31+
* @throws LockConflictedException
32+
* @throws NotSupportedException
33+
*/
34+
public function putOffExpiration(Key $key, $ttl);
35+
36+
/**
37+
* Check if the store supports extending the ttl of a resource.
38+
*
39+
* @throws LockConflictedException
40+
* @throws NotSupportedException
41+
*/
42+
public function supportsPutOffExpiration(): bool;
43+
}

src/Symfony/Component/Lock/Factory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Factory implements LoggerAwareInterface
2626

2727
private $store;
2828

29-
public function __construct(StoreInterface $store)
29+
public function __construct($store)
3030
{
3131
$this->store = $store;
3232

src/Symfony/Component/Lock/Lock.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Lock\Exception\LockConflictedException;
2020
use Symfony\Component\Lock\Exception\LockExpiredException;
2121
use Symfony\Component\Lock\Exception\LockReleasingException;
22+
use Symfony\Component\Lock\Exception\NotSupportedException;
2223

2324
/**
2425
* Lock is the default implementation of the LockInterface.
@@ -36,12 +37,12 @@ final class Lock implements LockInterface, LoggerAwareInterface
3637
private $dirty = false;
3738

3839
/**
39-
* @param Key $key Resource to lock
40-
* @param StoreInterface $store Store used to handle lock persistence
41-
* @param float|null $ttl Maximum expected lock duration in seconds
42-
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
40+
* @param Key $key Resource to lock
41+
* @param PersistStoreInterface $store Store used to handle lock persistence
42+
* @param float|null $ttl Maximum expected lock duration in seconds
43+
* @param bool $autoRelease Whether to automatically release the lock or not when the lock instance is destroyed
4344
*/
44-
public function __construct(Key $key, StoreInterface $store, float $ttl = null, bool $autoRelease = true)
45+
public function __construct(Key $key, PersistStoreInterface $store, float $ttl = null, bool $autoRelease = true)
4546
{
4647
$this->store = $store;
4748
$this->key = $key;
@@ -70,6 +71,9 @@ public function acquire($blocking = false)
7071
{
7172
try {
7273
if ($blocking) {
74+
if (!($this->store instanceof BlockingStoreInterface && $this->store->supportsWaitAndSave())) {
75+
throw new NotSupportedException();
76+
}
7377
$this->store->waitAndSave($this->key);
7478
} else {
7579
$this->store->save($this->key);
@@ -121,6 +125,9 @@ public function refresh($ttl = null)
121125

122126
try {
123127
$this->key->resetLifetime();
128+
if (!($this->store instanceof ExpiringStoreInterface && $this->store->supportsPutOffExpiration())) {
129+
throw new NotSupportedException();
130+
}
124131
$this->store->putOffExpiration($this->key, $ttl);
125132
$this->dirty = true;
126133

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock;
13+
14+
use Symfony\Component\Lock\Exception\LockAcquiringException;
15+
use Symfony\Component\Lock\Exception\LockConflictedException;
16+
use Symfony\Component\Lock\Exception\LockReleasingException;
17+
18+
/**
19+
* StoreInterface defines an interface to manipulate a lock store.
20+
*
21+
* @author Jérémy Derussé <[email protected]>
22+
*/
23+
interface PersistStoreInterface
24+
{
25+
/**
26+
* Stores the resource if it's not locked by someone else.
27+
*
28+
* @throws LockAcquiringException
29+
* @throws LockConflictedException
30+
*/
31+
public function save(Key $key);
32+
33+
/**
34+
* Removes a resource from the storage.
35+
*
36+
* @throws LockReleasingException
37+
*/
38+
public function delete(Key $key);
39+
40+
/**
41+
* Returns whether or not the resource exists in the storage.
42+
*
43+
* @return bool
44+
*/
45+
public function exists(Key $key);
46+
}

0 commit comments

Comments
 (0)