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

Commit

Permalink
Merge branch 'hotfix/10'
Browse files Browse the repository at this point in the history
Close #10
  • Loading branch information
weierophinney committed Jul 16, 2015
2 parents 986e3e5 + 67d4fd2 commit cc3b6f3
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 3 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -6,7 +6,8 @@ All notable changes to this project will be documented in this file, in reverse

### Added

- Nothing.
- [#10](https://github.com/zendframework/zend-cache/pull/10) adds TTL support
for the Redis adapter.

### Deprecated

Expand Down
92 changes: 90 additions & 2 deletions src/Storage/Adapter/Redis.php
Expand Up @@ -300,6 +300,25 @@ protected function internalAddItem(& $normalizedKey, & $value)
}
}

/**
* Internal method to touch an item.
*
* @param string &$normalizedKey Key which will be touched
*
* @return bool
* @throws Exception\RuntimeException
*/
protected function internalTouchItem(& $normalizedKey)
{
$redis = $this->getRedisResource();
try {
$ttl = $this->getOptions()->getTtl();
return (bool) $redis->expire($this->namespacePrefix . $normalizedKey, $ttl);
} catch (RedisResourceException $e) {
throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
}
}

/**
* Internal method to remove an item.
*
Expand Down Expand Up @@ -426,7 +445,11 @@ protected function internalGetCapabilities()
{
if ($this->capabilities === null) {
$this->capabilityMarker = new stdClass();
$minTtl = $this->resourceManager->getMajorVersion($this->resourceId) < 2 ? 0 : 1;

$redisVersion = $this->resourceManager->getMajorVersion($this->resourceId);
$minTtl = version_compare($redisVersion, '2', '<') ? 0 : 1;
$supportedMetadata = version_compare($redisVersion, '2', '>=') ? ['ttl'] : [];

//without serialization redis supports only strings for simple
//get/set methods
$this->capabilities = new Capabilities(
Expand All @@ -443,7 +466,7 @@ protected function internalGetCapabilities()
'object' => false,
'resource' => false,
],
'supportedMetadata' => [],
'supportedMetadata' => $supportedMetadata,
'minTtl' => $minTtl,
'maxTtl' => 0,
'staticTtl' => true,
Expand All @@ -458,4 +481,69 @@ protected function internalGetCapabilities()

return $this->capabilities;
}

/**
* {@inheritDoc}
*
* @throws Exception\ExceptionInterface
*/
protected function internalGetMetadata(& $normalizedKey)
{
$redis = $this->getRedisResource();
$metadata = [];

try {
$redisVersion = $this->resourceManager->getMajorVersion($this->resourceId);

// redis >= 2.8
// The command 'pttl' returns -2 if the item does not exist
// and -1 if the item has no associated expire
if (version_compare($redisVersion, '2.8', '>=')) {
$pttl = $redis->pttl($this->namespacePrefix . $normalizedKey);
if ($pttl <= -2) {
return false;
}
$metadata['ttl'] = ($pttl == -1) ? null : $pttl / 1000;

// redis >= 2.6
// The command 'pttl' returns -1 if the item does not exist or the item as no associated expire
} elseif (version_compare($redisVersion, '2.6', '>=')) {
$pttl = $redis->pttl($this->namespacePrefix . $normalizedKey);
if ($pttl <= -1) {
if (!$this->internalHasItem($normalizedKey)) {
return false;
}
$metadata['ttl'] = null;
} else {
$metadata['ttl'] = $pttl / 1000;
}

// redis >= 2
// The command 'pttl' is not supported but 'ttl'
// The command 'ttl' returns 0 if the item does not exist same as if the item is going to be expired
// NOTE: In case of ttl=0 we return false because the item is going to be expired in a very near future
// and then doesn't exist any more
} elseif (version_compare($redisVersion, '2', '>=')) {
$ttl = $redis->ttl($this->namespacePrefix . $normalizedKey);
if ($ttl <= -1) {
if (!$this->internalHasItem($normalizedKey)) {
return false;
}
$metadata['ttl'] = null;
} else {
$metadata['ttl'] = $ttl;
}

// redis < 2
// The commands 'pttl' and 'ttl' are not supported
// but item existence have to be checked
} elseif (!$this->internalHasItem($normalizedKey)) {
return false;
}
} catch (RedisResourceException $e) {
throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e);
}

return $metadata;
}
}
16 changes: 16 additions & 0 deletions test/Storage/Adapter/RedisTest.php
Expand Up @@ -312,4 +312,20 @@ public function testOptionsGetSetPassword()
$this->_options->setPassword($password);
$this->assertEquals($password, $this->_options->getPassword(), 'Password was set incorrectly using RedisOptions');
}

public function testTouchItem()
{
$key = 'key';

// no TTL
$this->_storage->getOptions()->setTtl(0);
$this->_storage->setItem($key, 'val');
$this->assertEquals(0, $this->_storage->getMetadata($key)['ttl']);

// touch with a specific TTL will add this TTL
$ttl = 1000;
$this->_storage->getOptions()->setTtl($ttl);
$this->assertTrue($this->_storage->touchItem($key));
$this->assertEquals($ttl, ceil($this->_storage->getMetadata($key)['ttl']));
}
}

0 comments on commit cc3b6f3

Please sign in to comment.