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

Commit

Permalink
[#2770] BC corrections
Browse files Browse the repository at this point in the history
- Re-instated MemcachedOptions::addServer(), and added optional $weight argument
  (defaults to 0, the default used by Memcached)
- Re-instated default server
- Re-instated ability to change namespaces
- Re-instated removed tests
- Fixed failing tests, and corrected assumptions in several tests (as internal
  implementation details had changed)
  • Loading branch information
weierophinney committed Oct 16, 2012
1 parent d1d1faa commit 978dda6
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 46 deletions.
56 changes: 34 additions & 22 deletions library/Zend/Cache/Storage/Adapter/Memcached.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,32 +73,44 @@ public function __construct($options = null)
*/
protected function getMemcachedResource()
{
if (!$this->memcachedResource) {
$options = $this->getOptions();
if ($this->memcachedResource) {
return $this->memcachedResource;
}

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

// init lib options
if (static::$extMemcachedMajorVersion > 1) {
$memcached->setOptions($options->getLibOptions());
} else {
foreach ($options->getLibOptions() as $k => $v) {
$memcached->setOption($k, $v);
}
}
$memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $options->getNamespace());
// use a configured resource or a new one
$memcached = $options->getMemcachedResource() ?: new MemcachedResource();

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

// Allow updating namespace
$this->getEventManager()->attach('option', function ($event) use ($memcached) {
$params = $event->getParams();
if (!isset($params['namespace'])) {
// Cannot set lib options after initialization
return;
}
$memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $params['namespace']);
});

// use the initialized resource
$this->memcachedResource = $memcached;
// init servers
$servers = $options->getServers();
if ($servers) {
$memcached->addServers($servers);
}

// use the initialized resource
$this->memcachedResource = $memcached;

return $this->memcachedResource;
}

Expand Down Expand Up @@ -404,8 +416,8 @@ protected function internalReplaceItem(& $normalizedKey, & $value)
*/
protected function internalCheckAndSetItem(& $token, & $normalizedKey, & $value)
{
$expiration = $this->expirationTime();
$memc = $this->getMemcachedResource();
$expiration = $this->expirationTime();
$result = $memc->cas($token, $normalizedKey, $value, $expiration);

if ($result === false) {
Expand Down Expand Up @@ -483,8 +495,8 @@ protected function internalRemoveItems(array & $normalizedKeys)
*/
protected function internalIncrementItem(& $normalizedKey, & $value)
{
$value = (int) $value;
$memc = $this->getMemcachedResource();
$value = (int) $value;
$newValue = $memc->increment($normalizedKey, $value);

if ($newValue === false) {
Expand Down Expand Up @@ -515,8 +527,8 @@ protected function internalIncrementItem(& $normalizedKey, & $value)
*/
protected function internalDecrementItem(& $normalizedKey, & $value)
{
$value = (int)$value;
$memc = $this->getMemcachedResource();
$value = (int)$value;
$newValue = $memc->decrement($normalizedKey, $value);

if ($newValue === false) {
Expand Down
74 changes: 54 additions & 20 deletions library/Zend/Cache/Storage/Adapter/MemcachedOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
*/
class MemcachedOptions extends AdapterOptions
{

/**
* A memcached resource to share
*
Expand All @@ -35,7 +34,13 @@ class MemcachedOptions extends AdapterOptions
*
* @var string
*/
protected $servers = array();
protected $servers = array(
array(
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 0,
),
);

/**
* List of Libmemcached options to set on initialize
Expand Down Expand Up @@ -92,6 +97,34 @@ public function getMemcachedResource()
return $this->memcachedResource;
}

/**
* Add a server to the list
*
* @param string $host
* @param int $port
* @param int $weight
* @return MemcachedOptions
*/
public function addServer($host, $port = 11211, $weight = 0)
{
$new = array(
'host' => $host,
'port' => $port,
'weight' => $weight
);

foreach ($this->servers as $server) {
$diff = array_diff($new, $server);
if (empty($diff)) {
// Done -- server is already present
return $this;
}
}

$this->servers[] = $new;
return $this;
}

/**
* Set a list of memcached servers to add on initialize
*
Expand All @@ -105,33 +138,40 @@ public function setServers($servers)
return $this->setServers(explode(',', $servers));
}

$list = array();
$this->servers = array();
foreach ($servers as $server) {

// default values
$host = null;
$port = 11211;
$weight = 1;

if (!is_array($server) && !is_string($server)) {
throw new Exception\InvalidArgumentException('Invalid server specification provided; must be an array or string');
}

// parse a single server from an array
if (is_array($server)) {
if (!isset($server[0]) && !isset($server['host'])) {
throw new Exception\InvalidArgumentException("Invalid list of servers given");
}

// array(array(<host>[, <port>[, <weight>]])[, ...])
if (isset($server[0])) {
$host = (string)$server[0];
$port = isset($server[1]) ? (int)$server[1] : $port;
$weight = isset($server[2]) ? (int)$server[2] : $weight;
$host = (string) $server[0];
$port = isset($server[1]) ? (int) $server[1] : $port;
$weight = isset($server[2]) ? (int) $server[2] : $weight;
}

// array(array('host' => <host>[, 'port' => <port>[, 'weight' => <weight>]])[, ...])
} elseif (isset($server['host'])) {
if (!isset($server[0]) && isset($server['host'])) {
$host = (string)$server['host'];
$port = isset($server['port']) ? (int)$server['port'] : $port;
$weight = isset($server['weight']) ? (int)$server['weight'] : $weight;
} else {
throw new Exception\InvalidArgumentException("Invalid list of servers given");
$port = isset($server['port']) ? (int) $server['port'] : $port;
$weight = isset($server['weight']) ? (int) $server['weight'] : $weight;
}
}

// parse a single server from a string
} else {
if (!is_array($server)) {
$server = trim($server);
if (strpos($server, '://') === false) {
$server = 'tcp://' . $server;
Expand All @@ -158,14 +198,9 @@ public function setServers($servers)
throw new Exception\InvalidArgumentException('The list of servers must contain a host value.');
}

$list[] = array(
'host' => $host,
'port' => $port,
'weight' => $weight
);
$this->addServer($host, $port, $weight);
}

$this->servers = $list;
return $this;
}

Expand Down Expand Up @@ -262,5 +297,4 @@ protected function normalizeLibOptionKey(& $key)
$key = (int) $key;
}
}

}
45 changes: 41 additions & 4 deletions tests/ZendTest/Cache/Storage/Adapter/MemcachedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,36 @@ public function setUp()

$this->_options = new Cache\Storage\Adapter\MemcachedOptions();
if (defined('TESTS_ZEND_CACHE_MEMCACHED_HOST') && defined('TESTS_ZEND_CACHE_MEMCACHED_PORT')) {
$this->_options->setServers(array(array(TESTS_ZEND_CACHE_MEMCACHED_HOST, TESTS_ZEND_CACHE_MEMCACHED_PORT)));
$this->_options->addServer(TESTS_ZEND_CACHE_MEMCACHED_HOST, TESTS_ZEND_CACHE_MEMCACHED_PORT);
} elseif (defined('TESTS_ZEND_CACHE_MEMCACHED_HOST')) {
$this->_options->setServers(TESTS_ZEND_CACHE_MEMCACHED_HOST);
$this->_options->addServer(TESTS_ZEND_CACHE_MEMCACHED_HOST);
}

$this->_storage = new Cache\Storage\Adapter\Memcached();
$this->_storage->setOptions($this->_options);
$this->_storage->flush();

parent::setUp();
}

public function testOptionsAddServer()
{
$options = new Cache\Storage\Adapter\MemcachedOptions();
$options->addServer('127.0.0.1', 11211);
$options->addServer('localhost');
$options->addServer('domain.com', 11215);

$servers = array(
array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 0),
array('host' => 'localhost', 'port' => 11211, 'weight' => 0),
array('host' => 'domain.com', 'port' => 11215, 'weight' => 0),
);

$this->assertEquals($options->getServers(), $servers);
$memcached = new Cache\Storage\Adapter\Memcached($options);
$this->assertEquals($memcached->getOptions()->getServers(), $servers);
}

public function getServersDefinitions()
{
$expectedServers = array(
Expand Down Expand Up @@ -95,14 +114,14 @@ public function getServersDefinitions()
*
* @dataProvider getServersDefinitions
*/
public function testOptionServers($servers, $expectedServers)
public function testOptionSetServers($servers, $expectedServers)
{
$options = new Cache\Storage\Adapter\MemcachedOptions();
$options->setServers($servers);
$this->assertEquals($expectedServers, $options->getServers());
}

public function testOptionLibOptions()
public function testLibOptionsSet()
{
$options = new Cache\Storage\Adapter\MemcachedOptions();

Expand All @@ -111,6 +130,24 @@ public function testOptionLibOptions()
));

$this->assertEquals($options->getLibOption(\Memcached::OPT_COMPRESSION), false);

$memcached = new Cache\Storage\Adapter\Memcached($options);
$this->assertEquals($memcached->getOptions()->getLibOptions(), array(
\Memcached::OPT_COMPRESSION => false
));
}

public function testNoOptionsSetsDefaultServer()
{
$memcached = new Cache\Storage\Adapter\Memcached();

$expected = array(array(
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 0,
));

$this->assertEquals($expected, $memcached->getOptions()->getServers());
}

public function tearDown()
Expand Down

0 comments on commit 978dda6

Please sign in to comment.