Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Show file tree
Hide file tree
Showing 3 changed files with 285 additions and 124 deletions.
176 changes: 99 additions & 77 deletions src/Storage/Adapter/Memcached.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace Zend\Cache\Storage\Adapter;

use Zend\Cache\Exception\LogicException;

use Memcached as MemcachedResource;
use stdClass;
use Traversable;
Expand Down Expand Up @@ -38,11 +40,11 @@ class Memcached extends AbstractAdapter implements
protected static $extMemcachedMajorVersion;

/**
* Memcached instance
* The memcached resource
*
* @var MemcachedResource
*/
protected $memcached;
protected $memcachedResource;

/**
* Constructor
Expand All @@ -62,53 +64,54 @@ public function __construct($options = null)
}

parent::__construct($options);
}

/**
* Initialize the internal memcached resource
*
* @return MemcachedResource
*/
protected function getMemcachedResource()
{
if ($this->memcachedResource) {
return $this->memcachedResource;
}

// It's ok to init the memcached instance as soon as possible because
// ext/memcached auto-connects to the server on first use
$this->memcached = new MemcachedResource();
$options = $this->getOptions();

// set lib options
// use a configured resource or a new one
$memcached = $options->getMemcachedResource() ?: new MemcachedResource();

// init lib options
if (static::$extMemcachedMajorVersion > 1) {
$this->memcached->setOptions($options->getLibOptions());
$memcached->setOptions($options->getLibOptions());
} else {
foreach ($options->getLibOptions() as $k => $v) {
$this->memcached->setOption($k, $v);
$memcached->setOption($k, $v);
}
}
$this->memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $options->getNamespace());

$servers = $options->getServers();
if (!$servers) {
$options->addServer('127.0.0.1', 11211);
$servers = $options->getServers();
}
$this->memcached->addServers($servers);
$memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $options->getNamespace());



// get notified on change options
$memc = $this->memcached;
$memcMV = static::$extMemcachedMajorVersion;
$this->getEventManager()->attach('option', function ($event) use ($memc, $memcMV) {
// Allow updating namespace
$this->getEventManager()->attach('option', function ($event) use ($memcached) {
$params = $event->getParams();

if (isset($params['lib_options'])) {
if ($memcMV > 1) {
$memc->setOptions($params['lib_options']);
} else {
foreach ($params['lib_options'] as $k => $v) {
$memc->setOption($k, $v);
}
}
if (!isset($params['namespace'])) {
// Cannot set lib options after initialization
return;
}
$memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $params['namespace']);
});

if (isset($params['namespace'])) {
$memc->setOption(MemcachedResource::OPT_PREFIX_KEY, $params['namespace']);
}
// init servers
$servers = $options->getServers();
if ($servers) {
$memcached->addServers($servers);
}

// TODO: update on change/add server(s)
});
// use the initialized resource
$this->memcachedResource = $memcached;

return $this->memcachedResource;
}

/* options */
Expand Down Expand Up @@ -152,8 +155,9 @@ public function getOptions()
*/
public function flush()
{
if (!$this->memcached->flush()) {
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
$memc = $this->getMemcachedResource();
if (!$memc->flush()) {
throw $this->getExceptionByResultCode($memc->getResultCode());
}
return true;
}
Expand All @@ -167,9 +171,10 @@ public function flush()
*/
public function getTotalSpace()
{
$stats = $this->memcached->getStats();
$memc = $this->getMemcachedResource();
$stats = $memc->getStats();
if ($stats === false) {
throw new Exception\RuntimeException($this->memcached->getResultMessage());
throw new Exception\RuntimeException($memc->getResultMessage());
}

$mem = array_pop($stats);
Expand All @@ -185,9 +190,10 @@ public function getTotalSpace()
*/
public function getAvailableSpace()
{
$stats = $this->memcached->getStats();
$memc = $this->getMemcachedResource();
$stats = $memc->getStats();
if ($stats === false) {
throw new Exception\RuntimeException($this->memcached->getResultMessage());
throw new Exception\RuntimeException($memc->getResultMessage());
}

$mem = array_pop($stats);
Expand All @@ -207,15 +213,17 @@ public function getAvailableSpace()
*/
protected function internalGetItem(& $normalizedKey, & $success = null, & $casToken = null)
{
$memc = $this->getMemcachedResource();

if (func_num_args() > 2) {
$result = $this->memcached->get($normalizedKey, null, $casToken);
$result = $memc->get($normalizedKey, null, $casToken);
} else {
$result = $this->memcached->get($normalizedKey);
$result = $memc->get($normalizedKey);
}

$success = true;
if ($result === false || $result === null) {
$rsCode = $this->memcached->getResultCode();
$rsCode = $memc->getResultCode();
if ($rsCode == MemcachedResource::RES_NOTFOUND) {
$result = null;
$success = false;
Expand All @@ -237,9 +245,10 @@ protected function internalGetItem(& $normalizedKey, & $success = null, & $casTo
*/
protected function internalGetItems(array & $normalizedKeys)
{
$result = $this->memcached->getMulti($normalizedKeys);
$memc = $this->getMemcachedResource();
$result = $memc->getMulti($normalizedKeys);
if ($result === false) {
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
throw $this->getExceptionByResultCode($memc->getResultCode());
}

return $result;
Expand All @@ -254,9 +263,10 @@ protected function internalGetItems(array & $normalizedKeys)
*/
protected function internalHasItem(& $normalizedKey)
{
$value = $this->memcached->get($normalizedKey);
$memc = $this->getMemcachedResource();
$value = $memc->get($normalizedKey);
if ($value === false || $value === null) {
$rsCode = $this->memcached->getResultCode();
$rsCode = $memc->getResultCode();
if ($rsCode == MemcachedResource::RES_SUCCESS) {
return true;
} elseif ($rsCode == MemcachedResource::RES_NOTFOUND) {
Expand All @@ -278,9 +288,10 @@ protected function internalHasItem(& $normalizedKey)
*/
protected function internalHasItems(array & $normalizedKeys)
{
$result = $this->memcached->getMulti($normalizedKeys);
$memc = $this->getMemcachedResource();
$result = $memc->getMulti($normalizedKeys);
if ($result === false) {
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
throw $this->getExceptionByResultCode($memc->getResultCode());
}

return array_keys($result);
Expand All @@ -295,9 +306,10 @@ protected function internalHasItems(array & $normalizedKeys)
*/
protected function internalGetMetadatas(array & $normalizedKeys)
{
$result = $this->memcached->getMulti($normalizedKeys);
$memc = $this->getMemcachedResource();
$result = $memc->getMulti($normalizedKeys);
if ($result === false) {
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
throw $this->getExceptionByResultCode($memc->getResultCode());
}

foreach ($result as & $value) {
Expand All @@ -319,9 +331,10 @@ protected function internalGetMetadatas(array & $normalizedKeys)
*/
protected function internalSetItem(& $normalizedKey, & $value)
{
$memc = $this->getMemcachedResource();
$expiration = $this->expirationTime();
if (!$this->memcached->set($normalizedKey, $value, $expiration)) {
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
if (!$memc->set($normalizedKey, $value, $expiration)) {
throw $this->getExceptionByResultCode($memc->getResultCode());
}

return true;
Expand All @@ -336,9 +349,10 @@ protected function internalSetItem(& $normalizedKey, & $value)
*/
protected function internalSetItems(array & $normalizedKeyValuePairs)
{
$memc = $this->getMemcachedResource();
$expiration = $this->expirationTime();
if (!$this->memcached->setMulti($normalizedKeyValuePairs, $expiration)) {
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
if (!$memc->setMulti($normalizedKeyValuePairs, $expiration)) {
throw $this->getExceptionByResultCode($memc->getResultCode());
}

return array();
Expand All @@ -354,12 +368,13 @@ protected function internalSetItems(array & $normalizedKeyValuePairs)
*/
protected function internalAddItem(& $normalizedKey, & $value)
{
$memc = $this->getMemcachedResource();
$expiration = $this->expirationTime();
if (!$this->memcached->add($normalizedKey, $value, $expiration)) {
if ($this->memcached->getResultCode() == MemcachedResource::RES_NOTSTORED) {
if (!$memc->add($normalizedKey, $value, $expiration)) {
if ($memc->getResultCode() == MemcachedResource::RES_NOTSTORED) {
return false;
}
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
throw $this->getExceptionByResultCode($memc->getResultCode());
}

return true;
Expand All @@ -375,12 +390,14 @@ protected function internalAddItem(& $normalizedKey, & $value)
*/
protected function internalReplaceItem(& $normalizedKey, & $value)
{
$memc = $this->getMemcachedResource();
$expiration = $this->expirationTime();
if (!$this->memcached->replace($normalizedKey, $value, $expiration)) {
if ($this->memcached->getResultCode() == MemcachedResource::RES_NOTSTORED) {
if (!$memc->replace($normalizedKey, $value, $expiration)) {
$rsCode = $memc->getResultCode();
if ($rsCode == MemcachedResource::RES_NOTSTORED) {
return false;
}
throw $this->getExceptionByResultCode($this->memcached->getResultCode());
throw $this->getExceptionByResultCode($rsCode);
}

return true;
Expand All @@ -399,11 +416,12 @@ protected function internalReplaceItem(& $normalizedKey, & $value)
*/
protected function internalCheckAndSetItem(& $token, & $normalizedKey, & $value)
{
$memc = $this->getMemcachedResource();
$expiration = $this->expirationTime();
$result = $this->memcached->cas($token, $normalizedKey, $value, $expiration);
$result = $memc->cas($token, $normalizedKey, $value, $expiration);

if ($result === false) {
$rsCode = $this->memcached->getResultCode();
$rsCode = $memc->getResultCode();
if ($rsCode !== 0 && $rsCode != MemcachedResource::RES_DATA_EXISTS) {
throw $this->getExceptionByResultCode($rsCode);
}
Expand All @@ -422,10 +440,11 @@ protected function internalCheckAndSetItem(& $token, & $normalizedKey, & $value)
*/
protected function internalRemoveItem(& $normalizedKey)
{
$result = $this->memcached->delete($normalizedKey);
$memc = $this->getMemcachedResource();
$result = $memc->delete($normalizedKey);

if ($result === false) {
$rsCode = $this->memcached->getResultCode();
$rsCode = $memc->getResultCode();
if ($rsCode == MemcachedResource::RES_NOTFOUND) {
return false;
} elseif ($rsCode != MemcachedResource::RES_SUCCESS) {
Expand All @@ -450,7 +469,8 @@ protected function internalRemoveItems(array & $normalizedKeys)
return parent::internalRemoveItems($normalizedKeys);
}

$rsCodes = $this->memcached->deleteMulti($normalizedKeys);
$memc = $this->getMemcachedResource();
$rsCodes = $memc->deleteMulti($normalizedKeys);

$missingKeys = array();
foreach ($rsCodes as $key => $rsCode) {
Expand All @@ -475,17 +495,18 @@ protected function internalRemoveItems(array & $normalizedKeys)
*/
protected function internalIncrementItem(& $normalizedKey, & $value)
{
$memc = $this->getMemcachedResource();
$value = (int) $value;
$newValue = $this->memcached->increment($normalizedKey, $value);
$newValue = $memc->increment($normalizedKey, $value);

if ($newValue === false) {
$rsCode = $this->memcached->getResultCode();
$rsCode = $memc->getResultCode();

// initial value
if ($rsCode == MemcachedResource::RES_NOTFOUND) {
$newValue = $value;
$this->memcached->add($normalizedKey, $newValue, $this->expirationTime());
$rsCode = $this->memcached->getResultCode();
$memc->add($normalizedKey, $newValue, $this->expirationTime());
$rsCode = $memc->getResultCode();
}

if ($rsCode) {
Expand All @@ -506,17 +527,18 @@ protected function internalIncrementItem(& $normalizedKey, & $value)
*/
protected function internalDecrementItem(& $normalizedKey, & $value)
{
$memc = $this->getMemcachedResource();
$value = (int)$value;
$newValue = $this->memcached->decrement($normalizedKey, $value);
$newValue = $memc->decrement($normalizedKey, $value);

if ($newValue === false) {
$rsCode = $this->memcached->getResultCode();
$rsCode = $memc->getResultCode();

// initial value
if ($rsCode == MemcachedResource::RES_NOTFOUND) {
$newValue = -$value;
$this->memcached->add($normalizedKey, $newValue, $this->expirationTime());
$rsCode = $this->memcached->getResultCode();
$memc->add($normalizedKey, $newValue, $this->expirationTime());
$rsCode = $memc->getResultCode();
}

if ($rsCode) {
Expand Down Expand Up @@ -609,7 +631,7 @@ protected function getExceptionByResultCode($code)
);

default:
return new Exception\RuntimeException($this->memcached->getResultMessage());
return new Exception\RuntimeException($this->getMemcachedResource()->getResultMessage());
}
}
}
Loading

0 comments on commit c076d41

Please sign in to comment.