From 363e9667ececca66a223934ded569425abd34cdf Mon Sep 17 00:00:00 2001 From: Jörn Friedrich Dreyer Date: Wed, 10 Dec 2014 12:24:20 +0100 Subject: Add Redis cache implementation, prefer over memcached, tests & config sample --- lib/private/memcache/factory.php | 4 +- lib/private/memcache/redis.php | 94 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 lib/private/memcache/redis.php (limited to 'lib/private') diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php index 8e47a8899fc..dba9e8a0e00 100644 --- a/lib/private/memcache/factory.php +++ b/lib/private/memcache/factory.php @@ -37,6 +37,8 @@ class Factory implements ICacheFactory { return new APCu($prefix); } elseif (APC::isAvailable()) { return new APC($prefix); + } elseif (Redis::isAvailable()) { + return new Redis($prefix); } elseif (Memcached::isAvailable()) { return new Memcached($prefix); } else { @@ -50,7 +52,7 @@ class Factory implements ICacheFactory { * @return bool */ public function isAvailable() { - return XCache::isAvailable() || APCu::isAvailable() || APC::isAvailable() || Memcached::isAvailable(); + return XCache::isAvailable() || APCu::isAvailable() || APC::isAvailable() || Redis::isAvailable() || Memcached::isAvailable(); } /** diff --git a/lib/private/memcache/redis.php b/lib/private/memcache/redis.php new file mode 100644 index 00000000000..f21619887d0 --- /dev/null +++ b/lib/private/memcache/redis.php @@ -0,0 +1,94 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Memcache; + +class Redis extends Cache { + + /** + * @var \Redis $cache + */ + private static $cache = null; + + public function __construct($prefix = '') { + parent::__construct($prefix); + if (is_null(self::$cache)) { + // TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays + self::$cache = new \Redis(); + $config = \OC::$server->getSystemConfig()->getValue('redis', array()); + if (isset($config['host'])) { + $host = $config['host']; + } else { + $host = '127.0.0.1'; + } + if (isset($config['port'])) { + $port = $config['port']; + } else { + $port = 6379; + } + if (isset($config['timeout'])) { + $timeout = $config['timeout']; + } else { + $timeout = 0.0; // unlimited + } + self::$cache->connect( $host, $port, $timeout ); + } + } + + /** + * entries in redis get namespaced to prevent collisions between ownCloud instances and users + */ + protected function getNameSpace() { + return $this->prefix; + } + + public function get($key) { + $result = self::$cache->get($this->getNamespace() . $key); + if ($result === false and ! self::$cache->exists($this->getNamespace() . $key)) { + return null; + } else { + return $result; + } + } + + public function set($key, $value, $ttl = 0) { + if ($ttl > 0) { + return self::$cache->setex($this->getNamespace() . $key, $ttl, $value); + } else { + return self::$cache->set($this->getNamespace() . $key, $value); + } + } + + public function hasKey($key) { + return self::$cache->exists($this->getNamespace() . $key); + } + + public function remove($key) { + if (self::$cache->delete($this->getNamespace() . $key)) { + return true; + } else { + return false; + } + + } + + public function clear($prefix = '') { + $prefix = $this->getNamespace() . $prefix.'*'; + $it = null; + self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY); + while($keys = self::$cache->scan($it, $prefix)) { + self::$cache->delete($keys); + } + return true; + } + + static public function isAvailable() { + return extension_loaded('redis'); + } +} + -- cgit v1.2.3