Skip to content

Commit 8f18556

Browse files
committed
Add missing lock connection string in FrameworkExtension
1 parent 0472dbf commit 8f18556

File tree

8 files changed

+80
-42
lines changed

8 files changed

+80
-42
lines changed

UPGRADE-4.4.md

+2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ Lock
162162
* Deprecated `Symfony\Component\Lock\StoreInterface` in favor of `Symfony\Component\Lock\BlockingStoreInterface` and
163163
`Symfony\Component\Lock\PersistingStoreInterface`.
164164
* `Factory` is deprecated, use `LockFactory` instead
165+
* Deprecated services `lock.store.flock`, `lock.store.semaphore`, `lock.store.memcached.abstract` and `lock.store.redis.abstract`,
166+
use `StoreFactory::createStore` instead.
165167

166168
Messenger
167169
---------

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

+5-36
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use Symfony\Bundle\FullStack;
2929
use Symfony\Component\Asset\PackageInterface;
3030
use Symfony\Component\BrowserKit\AbstractBrowser;
31-
use Symfony\Component\Cache\Adapter\AbstractAdapter;
3231
use Symfony\Component\Cache\Adapter\AdapterInterface;
3332
use Symfony\Component\Cache\Adapter\ArrayAdapter;
3433
use Symfony\Component\Cache\Adapter\ChainAdapter;
@@ -75,7 +74,6 @@
7574
use Symfony\Component\Lock\LockFactory;
7675
use Symfony\Component\Lock\LockInterface;
7776
use Symfony\Component\Lock\PersistingStoreInterface;
78-
use Symfony\Component\Lock\Store\FlockStore;
7977
use Symfony\Component\Lock\Store\StoreFactory;
8078
use Symfony\Component\Lock\StoreInterface;
8179
use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesTransportFactory;
@@ -1621,42 +1619,13 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
16211619
$storeDefinitions = [];
16221620
foreach ($resourceStores as $storeDsn) {
16231621
$storeDsn = $container->resolveEnvPlaceholders($storeDsn, null, $usedEnvs);
1624-
switch (true) {
1625-
case 'flock' === $storeDsn:
1626-
$storeDefinition = new Reference('lock.store.flock');
1627-
break;
1628-
case 0 === strpos($storeDsn, 'flock://'):
1629-
$flockPath = substr($storeDsn, 8);
1630-
1631-
$storeDefinitionId = '.lock.flock.store.'.$container->hash($storeDsn);
1632-
$container->register($storeDefinitionId, FlockStore::class)->addArgument($flockPath);
1633-
1634-
$storeDefinition = new Reference($storeDefinitionId);
1635-
break;
1636-
case 'semaphore' === $storeDsn:
1637-
$storeDefinition = new Reference('lock.store.semaphore');
1638-
break;
1639-
case $usedEnvs || preg_match('#^[a-z]++://#', $storeDsn):
1640-
if (!$container->hasDefinition($connectionDefinitionId = '.lock_connection.'.$container->hash($storeDsn))) {
1641-
$connectionDefinition = new Definition(\stdClass::class);
1642-
$connectionDefinition->setPublic(false);
1643-
$connectionDefinition->setFactory([AbstractAdapter::class, 'createConnection']);
1644-
$connectionDefinition->setArguments([$storeDsn, ['lazy' => true]]);
1645-
$container->setDefinition($connectionDefinitionId, $connectionDefinition);
1646-
}
1647-
1648-
$storeDefinition = new Definition(PersistingStoreInterface::class);
1649-
$storeDefinition->setPublic(false);
1650-
$storeDefinition->setFactory([StoreFactory::class, 'createStore']);
1651-
$storeDefinition->setArguments([new Reference($connectionDefinitionId)]);
1622+
$storeDefinition = new Definition(PersistingStoreInterface::class);
1623+
$storeDefinition->setFactory([StoreFactory::class, 'createStore']);
1624+
$storeDefinition->setArguments([$storeDsn]);
16521625

1653-
$container->setDefinition($storeDefinitionId = '.lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition);
1626+
$container->setDefinition($storeDefinitionId = '.lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition);
16541627

1655-
$storeDefinition = new Reference($storeDefinitionId);
1656-
break;
1657-
default:
1658-
throw new InvalidArgumentException(sprintf('Lock store DSN "%s" is not valid in resource "%s"', $storeDsn, $resourceName));
1659-
}
1628+
$storeDefinition = new Reference($storeDefinitionId);
16601629

16611630
$storeDefinitions[] = $storeDefinition;
16621631
}

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,22 @@
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 and will be removed in 5.0.</deprecated>
12+
</service>
1113

12-
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore" />
14+
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore">
15+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 and will be removed in 5.0.</deprecated>
16+
</service>
1317

1418
<service id="lock.store.memcached.abstract" class="Symfony\Component\Lock\Store\MemcachedStore" abstract="true">
1519
<argument /> <!-- Memcached connection service -->
20+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 and will be removed in 5.0.</deprecated>
1621
</service>
1722

1823
<service id="lock.store.redis.abstract" class="Symfony\Component\Lock\Store\RedisStore" abstract="true">
1924
<argument /> <!-- Redis connection service -->
25+
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4 and will be removed in 5.0.</deprecated>
2026
</service>
2127

2228
<service id="lock.store.combined.abstract" class="Symfony\Component\Lock\Store\CombinedStore" abstract="true">

src/Symfony/Component/Lock/CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ CHANGELOG
77
* added InvalidTtlException
88
* deprecated `StoreInterface` in favor of `BlockingStoreInterface` and `PersistingStoreInterface`
99
* `Factory` is deprecated, use `LockFactory` instead
10-
10+
* `StoreFactory::createStore` allows PDO and Zookeeper DSN.
11+
* deprecated services `lock.store.flock`, `lock.store.semaphore`, `lock.store.memcached.abstract` and `lock.store.redis.abstract`,
12+
use `StoreFactory::createStore` instead.
13+
1114
4.2.0
1215
-----
1316

src/Symfony/Component/Lock/Store/StoreFactory.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,19 @@ public static function createStore($connection)
5858
return new FlockStore(substr($connection, 8));
5959
case 'semaphore' === $connection:
6060
return new SemaphoreStore();
61-
case class_exists(AbstractAdapter::class) && preg_match('#^[a-z]++://#', $connection):
62-
return static::createStore(AbstractAdapter::createConnection($connection));
61+
case 0 === strpos($connection, 'redis://') && class_exists(AbstractAdapter::class):
62+
case 0 === strpos($connection, 'rediss://') && class_exists(AbstractAdapter::class):
63+
return new RedisStore(AbstractAdapter::createConnection($connection, ['lazy' => true]));
64+
case 0 === strpos($connection, 'memcached://') && class_exists(AbstractAdapter::class):
65+
return new MemcachedStore(AbstractAdapter::createConnection($connection, ['lazy' => true]));
66+
case 0 === strpos($connection, 'sqlite:'):
67+
case 0 === strpos($connection, 'mysql:'):
68+
case 0 === strpos($connection, 'pgsql:'):
69+
case 0 === strpos($connection, 'oci:'):
70+
case 0 === strpos($connection, 'sqlsrv:'):
71+
return new PdoStore($connection);
72+
case 0 === strpos($connection, 'zookeeper://'):
73+
return new ZookeeperStore(ZookeeperStore::createConnection($connection));
6374
default:
6475
throw new InvalidArgumentException(sprintf('Unsupported Connection: %s.', $connection));
6576
}

src/Symfony/Component/Lock/Store/ZookeeperStore.php

+19
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Lock\Store;
1313

14+
use Symfony\Component\Lock\Exception\InvalidArgumentException;
1415
use Symfony\Component\Lock\Exception\LockAcquiringException;
1516
use Symfony\Component\Lock\Exception\LockConflictedException;
1617
use Symfony\Component\Lock\Exception\LockReleasingException;
@@ -34,6 +35,24 @@ public function __construct(\Zookeeper $zookeeper)
3435
$this->zookeeper = $zookeeper;
3536
}
3637

38+
public static function createConnection(string $dsn): \Zookeeper
39+
{
40+
if (0 !== strpos($dsn, 'zookeeper:')) {
41+
throw new InvalidArgumentException(sprintf('Unsupported DSN: %s.', $dsn));
42+
}
43+
44+
if (false === $params = parse_url($dsn)) {
45+
throw new InvalidArgumentException(sprintf('Invalid Zookeeper DSN: %s.', $dsn));
46+
}
47+
48+
$host = $params['host'] ?? '';
49+
if (isset($params['port'])) {
50+
$host .= ':'.$params['port'];
51+
}
52+
53+
return new \Zookeeper($host);
54+
}
55+
3756
/**
3857
* {@inheritdoc}
3958
*/

src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php

+13
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Cache\Traits\RedisProxy;
1717
use Symfony\Component\Lock\Store\FlockStore;
1818
use Symfony\Component\Lock\Store\MemcachedStore;
19+
use Symfony\Component\Lock\Store\PdoStore;
1920
use Symfony\Component\Lock\Store\RedisStore;
2021
use Symfony\Component\Lock\Store\SemaphoreStore;
2122
use Symfony\Component\Lock\Store\StoreFactory;
@@ -50,13 +51,25 @@ public function validConnections()
5051
}
5152
if (class_exists(\Zookeeper::class)) {
5253
yield [$this->createMock(\Zookeeper::class), ZookeeperStore::class];
54+
yield ['zookeeper://localhost:2181', ZookeeperStore::class];
5355
}
5456
if (\extension_loaded('sysvsem')) {
5557
yield ['semaphore', SemaphoreStore::class];
5658
}
5759
if (class_exists(\Memcached::class) && class_exists(AbstractAdapter::class)) {
5860
yield ['memcached://server.com', MemcachedStore::class];
5961
}
62+
if (class_exists(\Redis::class) && class_exists(AbstractAdapter::class)) {
63+
yield ['redis://localhost', RedisStore::class];
64+
}
65+
if (class_exists(\PDO::class)) {
66+
yield ['sqlite:/tmp/sqlite.db', PdoStore::class];
67+
yield ['sqlite::memory:', PdoStore::class];
68+
yield ['mysql:host=localhost;dbname=test;', PdoStore::class];
69+
yield ['pgsql:host=localhost;dbname=test;', PdoStore::class];
70+
yield ['oci:host=localhost;dbname=test;', PdoStore::class];
71+
yield ['sqlsrv:server=localhost;Database=test', PdoStore::class];
72+
}
6073

6174
yield ['flock', FlockStore::class];
6275
yield ['flock://'.sys_get_temp_dir(), FlockStore::class];

src/Symfony/Component/Lock/Tests/Store/ZookeeperStoreTest.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,26 @@ public function getStore(): PersistingStoreInterface
3030
{
3131
$zookeeper_server = getenv('ZOOKEEPER_HOST').':2181';
3232

33-
$zookeeper = new \Zookeeper(implode(',', [$zookeeper_server]));
33+
$zookeeper = new \Zookeeper($zookeeper_server);
3434

3535
return StoreFactory::createStore($zookeeper);
3636
}
3737

38+
/**
39+
* @dataProvider provideValidConnectionString
40+
*/
41+
public function testCreateConnection(string $connectionString)
42+
{
43+
$this->assertInstanceOf(\Zookeeper::class, ZookeeperStore::createConnection($connectionString));
44+
}
45+
46+
public function provideValidConnectionString(): iterable
47+
{
48+
yield 'single host' => ['zookeeper://localhost:2181'];
49+
yield 'single multiple host' => ['zookeeper://localhost:2181,localhost:2181'];
50+
yield 'with extra attributes' => ['zookeeper://localhost:2181/path?option=value'];
51+
}
52+
3853
public function testSaveSucceedsWhenPathContainsMoreThanOneNode()
3954
{
4055
$store = $this->getStore();

0 commit comments

Comments
 (0)