From 5798dd6beccd9587339358c63420a1e7222f6959 Mon Sep 17 00:00:00 2001 From: Denis Golubovskiy Date: Thu, 24 Aug 2017 21:57:21 +0300 Subject: [PATCH] [Cache] Use options from Memcached DSN --- src/Symfony/Component/Cache/CHANGELOG.md | 1 + .../Tests/Adapter/MemcachedAdapterTest.php | 30 +++++++++++++ .../Component/Cache/Traits/MemcachedTrait.php | 45 ++++++++++--------- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Component/Cache/CHANGELOG.md b/src/Symfony/Component/Cache/CHANGELOG.md index e8172d94988d4..58b737dc950f3 100644 --- a/src/Symfony/Component/Cache/CHANGELOG.md +++ b/src/Symfony/Component/Cache/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 3.4.0 ----- + * added using options from Memcached DSN * added PruneableInterface so PSR-6 or PSR-16 cache implementations can declare support for manual stale cache pruning * added FilesystemTrait::prune() and PhpFilesTrait::prune() implementations * now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, and PhpFilesCache implement PruneableInterface and support diff --git a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php index 82b41c3b4d870..a506108c7bc03 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php @@ -162,4 +162,34 @@ public function provideServersSetting() ); } } + + /** + * @dataProvider provideDsnWithOptions + */ + public function testDsnWithOptions($dsn, array $options, array $expectedOptions) + { + $client = MemcachedAdapter::createConnection($dsn, $options); + + foreach ($expectedOptions as $option => $expect) { + $this->assertSame($expect, $client->getOption($option)); + } + } + + public function provideDsnWithOptions() + { + if (!class_exists('\Memcached')) { + self::markTestSkipped('Extension memcached required.'); + } + + yield array( + 'memcached://localhost:11222?retry_timeout=10', + array(\Memcached::OPT_RETRY_TIMEOUT => 8), + array(\Memcached::OPT_RETRY_TIMEOUT => 10), + ); + yield array( + 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2', + array(\Memcached::OPT_RETRY_TIMEOUT => 8), + array(\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8), + ); + } } diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index c2832946f98c2..ee990163a3d65 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -83,28 +83,6 @@ public static function createConnection($servers, array $options = array()) $client = new \Memcached($options['persistent_id']); $username = $options['username']; $password = $options['password']; - unset($options['persistent_id'], $options['username'], $options['password']); - $options = array_change_key_case($options, CASE_UPPER); - - // set client's options - $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); - $client->setOption(\Memcached::OPT_NO_BLOCK, true); - if (!array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) { - $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true); - } - foreach ($options as $name => $value) { - if (is_int($name)) { - continue; - } - if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) { - $value = constant('Memcached::'.$name.'_'.strtoupper($value)); - } - $opt = constant('Memcached::OPT_'.$name); - - unset($options[$name]); - $options[$opt] = $value; - } - $client->setOptions($options); // parse any DSN in $servers foreach ($servers as $i => $dsn) { @@ -139,11 +117,34 @@ public static function createConnection($servers, array $options = array()) if (isset($params['query'])) { parse_str($params['query'], $query); $params += $query; + $options = $query + $options; } $servers[$i] = array($params['host'], $params['port'], $params['weight']); } + // set client's options + unset($options['persistent_id'], $options['username'], $options['password'], $options['weight']); + $options = array_change_key_case($options, CASE_UPPER); + $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + $client->setOption(\Memcached::OPT_NO_BLOCK, true); + if (!array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) { + $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true); + } + foreach ($options as $name => $value) { + if (is_int($name)) { + continue; + } + if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) { + $value = constant('Memcached::'.$name.'_'.strtoupper($value)); + } + $opt = constant('Memcached::OPT_'.$name); + + unset($options[$name]); + $options[$opt] = $value; + } + $client->setOptions($options); + // set client's servers, taking care of persistent connections if (!$client->isPristine()) { $oldServers = array();