Permalink
Browse files

bug #23971 [Cache] Fix lazy Memcached connections (nicolas-grekas)

This PR was merged into the 3.3 branch.

Discussion
----------

[Cache] Fix lazy Memcached connections

| Q             | A
| ------------- | ---
| Branch?       | 3.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

By calling methods on the Memcached instance on cache pool initialization, we defeat the purpose of lazy proxies, if anyone wanted to use one.

Commits
-------

d8c400b [Cache] Fix lazy Memcached connections
  • Loading branch information...
fabpot committed Aug 26, 2017
2 parents 9db03c1 + d8c400b commit 91519895038a19458afadc44866f8dbdf423dbfe
Showing with 35 additions and 10 deletions.
  1. +35 −10 src/Symfony/Component/Cache/Traits/MemcachedTrait.php
@@ -30,6 +30,7 @@
);
private $client;
private $lazyClient;
public static function isSupported()
{
@@ -41,14 +42,18 @@ private function init(\Memcached $client, $namespace, $defaultLifetime)
if (!static::isSupported()) {
throw new CacheException('Memcached >= 2.2.0 is required');
}
$opt = $client->getOption(\Memcached::OPT_SERIALIZER);
if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
if (get_class($client) === 'Memcached') {
$opt = $client->getOption(\Memcached::OPT_SERIALIZER);
if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
}
$this->maxIdLength -= strlen($client->getOption(\Memcached::OPT_PREFIX_KEY));
$this->client = $client;
} else {
$this->lazyClient = $client;
}
$this->maxIdLength -= strlen($client->getOption(\Memcached::OPT_PREFIX_KEY));
parent::__construct($namespace, $defaultLifetime);
$this->client = $client;
}
/**
@@ -191,7 +196,7 @@ protected function doSave(array $values, $lifetime)
$lifetime += time();
}
return $this->checkResultCode($this->client->setMulti($values, $lifetime));
return $this->checkResultCode($this->getClient()->setMulti($values, $lifetime));
}
/**
@@ -201,7 +206,7 @@ protected function doFetch(array $ids)
{
$unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
try {
return $this->checkResultCode($this->client->getMulti($ids));
return $this->checkResultCode($this->getClient()->getMulti($ids));
} catch (\Error $e) {
throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
} finally {
@@ -214,7 +219,7 @@ protected function doFetch(array $ids)
*/
protected function doHave($id)
{
return false !== $this->client->get($id) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode());
return false !== $this->getClient()->get($id) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode());
}
/**
@@ -223,7 +228,7 @@ protected function doHave($id)
protected function doDelete(array $ids)
{
$ok = true;
foreach ($this->checkResultCode($this->client->deleteMulti($ids)) as $result) {
foreach ($this->checkResultCode($this->getClient()->deleteMulti($ids)) as $result) {
if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) {
$ok = false;
}
@@ -237,7 +242,7 @@ protected function doDelete(array $ids)
*/
protected function doClear($namespace)
{
return $this->checkResultCode($this->client->flush());
return $this->checkResultCode($this->getClient()->flush());
}
private function checkResultCode($result)
@@ -250,4 +255,24 @@ private function checkResultCode($result)
throw new CacheException(sprintf('MemcachedAdapter client error: %s.', strtolower($this->client->getResultMessage())));
}
/**
* @return \Memcached
*/
private function getClient()
{
if ($this->client) {
return $this->client;
}
$opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER);
if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) {
throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
}
if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) {
throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix));
}
return $this->client = $this->lazyClient;
}
}

0 comments on commit 9151989

Please sign in to comment.