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 34a22f9

Browse filesBrowse files
committed
Reduce lock service visibility
1 parent 751e361 commit 34a22f9
Copy full SHA for 34a22f9

File tree

4 files changed

+174
-77
lines changed
Filter options

4 files changed

+174
-77
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+15-20Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@
5353
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
5454
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
5555
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
56+
use Symfony\Component\Lock\Factory;
5657
use Symfony\Component\Lock\Lock;
58+
use Symfony\Component\Lock\LockInterface;
5759
use Symfony\Component\Lock\Store\StoreFactory;
60+
use Symfony\Component\Lock\StoreInterface;
5861
use Symfony\Component\PropertyAccess\PropertyAccessor;
5962
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
6063
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
@@ -1508,19 +1511,10 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
15081511
}
15091512
}
15101513

1511-
/**
1512-
* Loads lock configuration.
1513-
*
1514-
* @param array $config
1515-
* @param ContainerBuilder $container
1516-
* @param XmlFileLoader $loader
1517-
*/
15181514
private function registerLockConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
15191515
{
15201516
$loader->load('lock.xml');
15211517

1522-
$container->getDefinition('lock.store.flock')->replaceArgument(0, sys_get_temp_dir());
1523-
15241518
foreach ($config['resources'] as $resourceName => $resourceStores) {
15251519
if (0 === count($resourceStores)) {
15261520
continue;
@@ -1538,24 +1532,22 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
15381532
$storeDefinition = new Reference('lock.store.semaphore');
15391533
break;
15401534
case $usedEnvs || preg_match('#^[a-z]++://#', $storeDsn):
1541-
if (!$container->hasDefinition($connectionDefinitionId = md5($storeDsn))) {
1535+
if (!$container->hasDefinition($connectionDefinitionId = $container->hash($storeDsn))) {
15421536
$connectionDefinition = new Definition(\stdClass::class);
15431537
$connectionDefinition->setPublic(false);
15441538
$connectionDefinition->setFactory(array(StoreFactory::class, 'createConnection'));
15451539
$connectionDefinition->setArguments(array($storeDsn));
15461540
$container->setDefinition($connectionDefinitionId, $connectionDefinition);
15471541
}
15481542

1549-
$storeDefinition = new Definition(\stdClass::class);
1543+
$storeDefinition = new Definition(StoreInterface::class);
1544+
$storeDefinition->setPublic(false);
15501545
$storeDefinition->setFactory(array(StoreFactory::class, 'createStore'));
15511546
$storeDefinition->setArguments(array(new Reference($connectionDefinitionId)));
15521547

1553-
$container->setDefinition($storeDefinitionId = 'lock.'.$resourceName.'.store.'.md5($storeDsn), $storeDefinition);
1548+
$container->setDefinition($storeDefinitionId = 'lock.'.$resourceName.'.store.'.$container->hash($storeDsn), $storeDefinition);
15541549

15551550
$storeDefinition = new Reference($storeDefinitionId);
1556-
break;
1557-
case $usedEnvs:
1558-
15591551
break;
15601552
default:
15611553
throw new InvalidArgumentException(sprintf('Lock store DSN "%s" is not valid in resource "%s"', $storeDsn, $resourceName));
@@ -1570,26 +1562,29 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
15701562
$combinedDefinition->replaceArgument(0, $storeDefinitions);
15711563
$container->setDefinition('lock.'.$resourceName.'.store', $combinedDefinition);
15721564
} else {
1573-
$container->setAlias('lock.'.$resourceName.'.store', new Alias((string) $storeDefinitions[0]));
1565+
$container->setAlias('lock.'.$resourceName.'.store', new Alias((string) $storeDefinitions[0], false));
15741566
}
15751567

15761568
// Generate factories for each resource
15771569
$factoryDefinition = new ChildDefinition('lock.factory.abstract');
15781570
$factoryDefinition->replaceArgument(0, new Reference('lock.'.$resourceName.'.store'));
1579-
$factoryDefinition->setPublic(true);
15801571
$container->setDefinition('lock.'.$resourceName.'.factory', $factoryDefinition);
15811572

15821573
// Generate services for lock instances
15831574
$lockDefinition = new Definition(Lock::class);
1575+
$lockDefinition->setPublic(false);
15841576
$lockDefinition->setFactory(array(new Reference('lock.'.$resourceName.'.factory'), 'createLock'));
15851577
$lockDefinition->setArguments(array($resourceName));
15861578
$container->setDefinition('lock.'.$resourceName, $lockDefinition);
15871579

15881580
// provide alias for default resource
15891581
if ('default' === $resourceName) {
1590-
$container->setAlias('lock.store', new Alias('lock.'.$resourceName.'.store'));
1591-
$container->setAlias('lock.factory', new Alias('lock.'.$resourceName.'.factory'));
1592-
$container->setAlias('lock', new Alias('lock.'.$resourceName));
1582+
$container->setAlias('lock.store', new Alias('lock.'.$resourceName.'.store', false));
1583+
$container->setAlias('lock.factory', new Alias('lock.'.$resourceName.'.factory', false));
1584+
$container->setAlias('lock', new Alias('lock.'.$resourceName, false));
1585+
$container->setAlias(StoreInterface::class, new Alias('lock.store', false));
1586+
$container->setAlias(Factory::class, new Alias('lock.factory', false));
1587+
$container->setAlias(LockInterface::class, new Alias('lock', false));
15931588
}
15941589
}
15951590
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/lock.xml
+14-9Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,34 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<services>
8-
9-
<service id="lock.store.flock" class="Symfony\Component\Lock\Store\FlockStore" public="false">
10-
<argument /> <!-- lock directory -->
8+
<defaults public="false" />
9+
10+
<service id="lock.store.flock" class="Symfony\Component\Lock\Store\FlockStore">
11+
<argument type="service">
12+
<service class="string">
13+
<factory function="sys_get_temp_dir"/>
14+
</service>
15+
</argument>
1116
</service>
1217

13-
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore" public="false" />
18+
<service id="lock.store.semaphore" class="Symfony\Component\Lock\Store\SemaphoreStore"/>
1419

15-
<service id="lock.store.memcached.abstract" class="Symfony\Component\Lock\Store\MemcachedStore" abstract="true" public="false">
20+
<service id="lock.store.memcached.abstract" class="Symfony\Component\Lock\Store\MemcachedStore" abstract="true">
1621
<argument /> <!-- Memcached connection service -->
1722
</service>
1823

19-
<service id="lock.store.redis.abstract" class="Symfony\Component\Lock\Store\RedisStore" abstract="true" public="false">
24+
<service id="lock.store.redis.abstract" class="Symfony\Component\Lock\Store\RedisStore" abstract="true">
2025
<argument /> <!-- Redis connection service -->
2126
</service>
2227

23-
<service id="lock.store.combined.abstract" class="Symfony\Component\Lock\Store\CombinedStore" abstract="true" public="false">
28+
<service id="lock.store.combined.abstract" class="Symfony\Component\Lock\Store\CombinedStore" abstract="true">
2429
<argument /> <!-- List of stores -->
2530
<argument type="service" id="lock.strategy.majority" /> <!-- Strategy -->
2631
</service>
2732

28-
<service id="lock.strategy.majority" class="Symfony\Component\Lock\Strategy\ConsensusStrategy" public="false" />
33+
<service id="lock.strategy.majority" class="Symfony\Component\Lock\Strategy\ConsensusStrategy"/>
2934

30-
<service id="lock.factory.abstract" class="Symfony\Component\Lock\Factory" abstract="true" public="false">
35+
<service id="lock.factory.abstract" class="Symfony\Component\Lock\Factory" abstract="true">
3136
<tag name="monolog.logger" channel="lock" />
3237
<argument /> <!-- Store -->
3338
<call method="setLogger">

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Store/MemcachedStore.php
+49-48Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,15 @@ public function __construct(\Memcached $memcached, $initialTtl = 300)
6767
* - 'memcached://user:pass@localhost?weight=33'
6868
* - array(array('localhost', 11211, 33))
6969
*
70-
* @param string $dsn
71-
* @param array $options See self::$defaultConnectionOptions
70+
* @param string $dsn A server or A DSN
71+
* @param array $options An array of options
7272
*
7373
* @return \Memcached
7474
*
75-
* @throws \ErrorEception When invalid options or dsn are provided
75+
* @throws \ErrorEception When invalid options or server are provided
7676
*/
77-
public static function createConnection($dsn, array $options = array())
77+
public static function createConnection($server, array $options = array())
7878
{
79-
if (0 !== strpos($dsn, 'memcached://')) {
80-
throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s does not start with "memcached://"', $dsn));
81-
}
8279
if (!static::isSupported()) {
8380
throw new InvalidArgumentException('Memcached extension is required');
8481
}
@@ -88,10 +85,46 @@ public static function createConnection($dsn, array $options = array())
8885
$client = new \Memcached($options['persistent_id']);
8986
$username = $options['username'];
9087
$password = $options['password'];
91-
unset($options['persistent_id'], $options['username'], $options['password']);
92-
$options = array_change_key_case($options, CASE_UPPER);
88+
89+
// parse any DSN in $server
90+
if (is_string($server)) {
91+
if (0 !== strpos($server, 'memcached://')) {
92+
throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s does not start with "memcached://"', $server));
93+
}
94+
$params = preg_replace_callback('#^memcached://(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
95+
if (!empty($m[1])) {
96+
list($username, $password) = explode(':', $m[1], 2) + array(1 => null);
97+
}
98+
99+
return 'file://';
100+
}, $server);
101+
if (false === $params = parse_url($params)) {
102+
throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $server));
103+
}
104+
if (!isset($params['host']) && !isset($params['path'])) {
105+
throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $server));
106+
}
107+
if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
108+
$params['weight'] = $m[1];
109+
$params['path'] = substr($params['path'], 0, -strlen($m[0]));
110+
}
111+
$params += array(
112+
'host' => isset($params['host']) ? $params['host'] : $params['path'],
113+
'port' => isset($params['host']) ? 11211 : null,
114+
'weight' => 0,
115+
);
116+
if (isset($params['query'])) {
117+
parse_str($params['query'], $query);
118+
$params += $query;
119+
$options = $query + $options;
120+
}
121+
122+
$server = array($params['host'], $params['port'], $params['weight']);
123+
}
93124

94125
// set client's options
126+
unset($options['persistent_id'], $options['username'], $options['password'], $options['weight']);
127+
$options = array_change_key_case($options, CASE_UPPER);
95128
$client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
96129
$client->setOption(\Memcached::OPT_NO_BLOCK, false);
97130
if (!array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) {
@@ -111,36 +144,6 @@ public static function createConnection($dsn, array $options = array())
111144
}
112145
$client->setOptions($options);
113146

114-
// parse any DSN in $servers
115-
$params = preg_replace_callback('#^memcached://(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) {
116-
if (!empty($m[1])) {
117-
list($username, $password) = explode(':', $m[1], 2) + array(1 => null);
118-
}
119-
120-
return 'file://';
121-
}, $dsn);
122-
if (false === $params = parse_url($params)) {
123-
throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $dsn));
124-
}
125-
if (!isset($params['host']) && !isset($params['path'])) {
126-
throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $dsn));
127-
}
128-
if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) {
129-
$params['weight'] = $m[1];
130-
$params['path'] = substr($params['path'], 0, -strlen($m[0]));
131-
}
132-
$params += array(
133-
'host' => isset($params['host']) ? $params['host'] : $params['path'],
134-
'port' => isset($params['host']) ? 11211 : null,
135-
'weight' => 0,
136-
);
137-
if (isset($params['query'])) {
138-
parse_str($params['query'], $query);
139-
$params += $query;
140-
}
141-
142-
$servers = array(array($params['host'], $params['port'], $params['weight']));
143-
144147
// set client's servers, taking care of persistent connections
145148
if (!$client->isPristine()) {
146149
$oldServers = array();
@@ -149,22 +152,20 @@ public static function createConnection($dsn, array $options = array())
149152
}
150153

151154
$newServers = array();
152-
foreach ($servers as $server) {
153-
if (1 < count($server)) {
154-
$server = array_values($server);
155-
unset($server[2]);
156-
$server[1] = (int) $server[1];
157-
}
158-
$newServers[] = $server;
155+
if (1 < count($server)) {
156+
$server = array_values($server);
157+
unset($server[2]);
158+
$server[1] = (int) $server[1];
159159
}
160+
$newServers[] = $server;
160161

161162
if ($oldServers !== $newServers) {
162163
// before resetting, ensure $servers is valid
163-
$client->addServers($servers);
164+
$client->addServers(array($server));
164165
$client->resetServerList();
165166
}
166167
}
167-
$client->addServers($servers);
168+
$client->addServers(array($server));
168169

169170
if (null !== $username || null !== $password) {
170171
if (!method_exists($client, 'setSaslAuthData')) {

‎src/Symfony/Component/Lock/Tests/Store/MemcachedStoreTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Lock/Tests/Store/MemcachedStoreTest.php
+96Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,100 @@ public function testAbortAfterExpiration()
5454
{
5555
$this->markTestSkipped('Memcached expects a TTL greater than 1 sec. Simulating a slow network is too hard');
5656
}
57+
58+
public function testDefaultOptions()
59+
{
60+
$this->assertTrue(MemcachedStore::isSupported());
61+
62+
$client = MemcachedStore::createConnection('memcached://127.0.0.1');
63+
64+
$this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
65+
$this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL));
66+
$this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
67+
}
68+
69+
/**
70+
* @dataProvider provideServersSetting
71+
*/
72+
public function testServersSetting($dsn, $host, $port)
73+
{
74+
$client1 = MemcachedStore::createConnection($dsn);
75+
$client3 = MemcachedStore::createConnection(array($host, $port));
76+
$expect = array(
77+
'host' => $host,
78+
'port' => $port,
79+
);
80+
81+
$f = function ($s) { return array('host' => $s['host'], 'port' => $s['port']); };
82+
$this->assertSame(array($expect), array_map($f, $client1->getServerList()));
83+
$this->assertSame(array($expect), array_map($f, $client3->getServerList()));
84+
}
85+
86+
public function provideServersSetting()
87+
{
88+
yield array(
89+
'memcached://127.0.0.1/50',
90+
'127.0.0.1',
91+
11211,
92+
);
93+
yield array(
94+
'memcached://localhost:11222?weight=25',
95+
'localhost',
96+
11222,
97+
);
98+
if (ini_get('memcached.use_sasl')) {
99+
yield array(
100+
'memcached://user:password@127.0.0.1?weight=50',
101+
'127.0.0.1',
102+
11211,
103+
);
104+
}
105+
yield array(
106+
'memcached:///var/run/memcached.sock?weight=25',
107+
'/var/run/memcached.sock',
108+
0,
109+
);
110+
yield array(
111+
'memcached:///var/local/run/memcached.socket?weight=25',
112+
'/var/local/run/memcached.socket',
113+
0,
114+
);
115+
if (ini_get('memcached.use_sasl')) {
116+
yield array(
117+
'memcached://user:password@/var/local/run/memcached.socket?weight=25',
118+
'/var/local/run/memcached.socket',
119+
0,
120+
);
121+
}
122+
}
123+
124+
/**
125+
* @dataProvider provideDsnWithOptions
126+
*/
127+
public function testDsnWithOptions($dsn, array $options, array $expectedOptions)
128+
{
129+
$client = MemcachedStore::createConnection($dsn, $options);
130+
131+
foreach ($expectedOptions as $option => $expect) {
132+
$this->assertSame($expect, $client->getOption($option));
133+
}
134+
}
135+
136+
public function provideDsnWithOptions()
137+
{
138+
if (!class_exists('\Memcached')) {
139+
self::markTestSkipped('Extension memcached required.');
140+
}
141+
142+
yield array(
143+
'memcached://localhost:11222?retry_timeout=10',
144+
array(\Memcached::OPT_RETRY_TIMEOUT => 8),
145+
array(\Memcached::OPT_RETRY_TIMEOUT => 10),
146+
);
147+
yield array(
148+
'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2',
149+
array(\Memcached::OPT_RETRY_TIMEOUT => 8),
150+
array(\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8),
151+
);
152+
}
57153
}

0 commit comments

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