switch to using watch to implement cas and cad on redis

This commit is contained in:
Robin Appelman 2015-06-08 18:01:49 +02:00
parent 520a741876
commit a9ff242f6a
1 changed files with 22 additions and 30 deletions

View File

@ -31,10 +31,6 @@ class Redis extends Cache implements IMemcache {
*/
private static $cache = null;
private static $casScript;
private static $cadScript;
public function __construct($prefix = '') {
parent::__construct($prefix);
if (is_null(self::$cache)) {
@ -59,29 +55,6 @@ class Redis extends Cache implements IMemcache {
self::$cache->connect($host, $port, $timeout);
self::$casScript = self::$cache->script('load', '
local key = ARGV[1]
local old = ARGV[2]
local new = ARGV[3]
if redis.call(\'get\', key) == old then
redis.call(\'set\', key, new)
return true
end
return false');
self::$cadScript = self::$cache->script('load', '
local key = ARGV[1]
local old = ARGV[2]
if redis.call(\'get\', key) == old then
redis.call(\'del\', key)
return true
end
return false');
if (isset($config['dbindex'])) {
self::$cache->select($config['dbindex']);
}
@ -184,7 +157,18 @@ return false');
* @return bool
*/
public function cas($key, $old, $new) {
return (bool) self::$cache->evalSha(self::$casScript, [$this->getNamespace() . $key, json_encode($old), json_encode($new)]);
if (!is_int($new)) {
$new = json_encode($new);
}
self::$cache->watch($this->getNamespace() . $key);
if ($this->get($key) === $old) {
$result = self::$cache->multi()
->set($this->getNamespace() . $key, $new)
->exec();
return ($result === false) ? false : true;
}
self::$cache->unwatch();
return false;
}
/**
@ -195,12 +179,20 @@ return false');
* @return bool
*/
public function cad($key, $old) {
return (bool)self::$cache->evalSha(self::$cadScript, [$this->getNamespace() . $key, json_encode($old)]);
self::$cache->watch($this->getNamespace() . $key);
if ($this->get($key) === $old) {
$result = self::$cache->multi()
->del($this->getNamespace() . $key)
->exec();
return ($result === false) ? false : true;
}
self::$cache->unwatch();
return false;
}
static public function isAvailable() {
return extension_loaded('redis')
&& version_compare(phpversion('redis'), '2.2.5', '>=');
&& version_compare(phpversion('redis'), '2.2.5', '>=');
}
}