Ollie Rutherfurd avatar Ollie Rutherfurd committed bfecc23

add a Redis backend

Comments (0)

Files changed (4)

docs/build/api.rst

 .. automodule:: dogpile.cache.backends.memcached
     :members:
 
+.. automodule:: dogpile.cache.backends.redis
+    :members:
+
 .. automodule:: dogpile.cache.backends.file
     :members:
 

dogpile/cache/backends/__init__.py

 register_backend("dogpile.cache.bmemcached", "dogpile.cache.backends.memcached", "BMemcachedBackend")
 register_backend("dogpile.cache.memcached", "dogpile.cache.backends.memcached", "MemcachedBackend")
 register_backend("dogpile.cache.memory", "dogpile.cache.backends.memory", "MemoryBackend")
+register_backend("dogpile.cache.redis", "dogpile.cache.backends.redis", "RedisBackend")

dogpile/cache/backends/redis.py

+from __future__ import absolute_import
+from dogpile.cache.api import CacheBackend, NO_VALUE
+from dogpile.cache.util import pickle
+
+
+class RedisBackend(CacheBackend):
+    """A `Redis <http://redis.io/>`_ backend.
+
+    Example configuration::
+
+        from dogpile.cache import make_region
+
+        region = make_region().configure(
+            'dogpile.cache.redis',
+            arguments = {
+                'host': 'localhost',
+                'port': 6379,
+                'db': 0,
+                'redis_expiration_time': 60*60*2,   # 2 hours
+                }
+        )
+
+    Arguments accepted in the arguments dictionary:
+
+    :param host: string, default is ``localhost``.
+
+    :param port: integer, default is ``6379``.
+
+    :param db: integer, default is ``0``.
+
+    :param redis_expiration_time: integer, number of seconds after setting
+    a value that Redis should expire it.  This should be larger than dogpile's
+    cache expiration.  By default no expiration is set.
+    """
+
+    def __init__(self, arguments):
+        self._imports()
+        self.host = arguments.pop('host', 'localhost')
+        self.port = arguments.pop('port', 6379)
+        self.db = arguments.pop('db', 0)
+        self.redis_expiration_time = arguments.pop('redis_expiration_time', 0)
+        self.client = self._create_client()
+
+    def _imports(self):
+        # defer imports until backend is used
+        global redis
+        import redis
+
+    def _create_client(self):
+        # creates client instace (so test harness can test connection)
+        return redis.StrictRedis(host=self.host, port=self.port, db=self.db)
+
+    def get(self, key):
+        value = self.client.get(key)
+        if value is None:
+            return NO_VALUE
+        return pickle.loads(value)
+
+    def set(self, key, value):
+        if self.redis_expiration_time:
+            self.client.setex(key, self.redis_expiration_time,
+                    pickle.dumps(value))
+        else:
+            self.client.set(key, pickle.dumps(value))
+
+    def delete(self, key):
+        self.client.delete(key)

tests/cache/test_redis_backend.py

+from ._fixtures import _GenericBackendTest
+from nose import SkipTest
+
+class _TestRedisConn(object):
+    @classmethod
+    def _check_backend_available(cls, backend):
+        try:
+            client = backend._create_client()
+            client.set("x", "y")
+            assert client.get("x") == "y"
+            client.delete("x")
+        except:
+            raise SkipTest(
+                "redis is not running or "
+                "otherwise not functioning correctly")
+
+
+class RedisTest(_TestRedisConn, _GenericBackendTest):
+    backend = 'dogpile.cache.redis'
+    config_args = {
+        "arguments":{
+            'host': '127.0.0.1',
+            'port': 6379,
+            'db': 0,
+            }
+    }
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.