Browse Source

Added a Redis result store backend.

Ask Solem 15 years ago
parent
commit
95f102c8c4
2 changed files with 160 additions and 12 deletions
  1. 90 0
      celery/backends/redis.py
  2. 70 12
      docs/configuration.rst

+ 90 - 0
celery/backends/redis.py

@@ -0,0 +1,90 @@
+"""celery.backends.tyrant"""
+from django.core.exceptions import ImproperlyConfigured
+from celery.backends.base import KeyValueStoreBackend
+from celery.loaders import settings
+
+try:
+    import redis
+except ImportError:
+    redis = None
+
+
+class Backend(KeyValueStoreBackend):
+    """Redis based task backend store.
+
+    .. attribute:: redis_host
+
+        The hostname to the Redis server.
+
+    .. attribute:: redis_port
+
+        The port to the Redis server.
+
+        Raises :class:`django.core.exceptions.ImproperlyConfigured` if
+        :setting:`REDIS_HOST` or :setting:`REDIS_PORT` is not set.
+
+    """
+    redis_host = None
+    redis_port = None
+    redis_db = "celery_results"
+    redis_timeout = None
+    redis_connect_retry = None
+
+    def __init__(self, redis_host=None, redis_port=None, redis_db=None):
+        if not redis:
+            raise ImproperlyConfigured(
+                    "You need to install the redis library in order to use "
+                  + "Redis result store backend.")
+        self.redis_host = redis_host or \
+                            getattr(settings, "REDIS_HOST", self.redis_host)
+        self.redis_port = redis_port or \
+                            getattr(settings, "REDIS_PORT", self.redis_port)
+        self.redis_db = redis_db or \
+                            getattr(settings, "REDIS_DB", self.redis_db)
+        self.redis_timeout = redis_timeout or \
+                            getattr(settings, "REDIS_TIMEOUT",
+                                    self.redis_timeout)
+        self.redis_connect_retry = redis_connect_retry or \
+                            getattr(settings, "REDIS_CONNECT_RETRY",
+                                    self.redis_connect_retry)
+        if self.redis_port:
+            self.redis_port = int(self.redis_port)
+        if not self.redis_host or not self.redis_port:
+            raise ImproperlyConfigured(
+                "In order to use the Redis result store backend, you have to "
+                "set the REDIS_HOST and REDIS_PORT settings")
+        super(Backend, self).__init__()
+        self._connection = None
+
+    def open(self):
+        """Get :class:`redis.Redis`` instance with the current
+        server configuration.
+
+        The connection is then cached until you do an
+        explicit :meth:`close`.
+
+        """
+        # connection overrides bool()
+        if self._connection is None:
+            self._connection = redis.Redis(host=self.redis_host,
+                                    port=self.redis_port,
+                                    db=self.redis_db,
+                                    timeout=self.redis_timeout,
+                                    connect_retry=self.redis_connect_retry)
+        return self._connection
+
+    def close(self):
+        """Close the redis connection and remove the cache."""
+        # connection overrides bool() # XXX Was the case with tyrant lib!
+        if self._connection is not None:
+            self._connection.close()
+            self._connection = None
+
+    def process_cleanup(self):
+        self.close()
+
+    def get(self, key):
+        return self.open().get(key)
+
+    def set(self, key, value):
+        self.open().set(key, value)

+ 70 - 12
docs/configuration.rst

@@ -1,5 +1,4 @@
 ============================
-
  Configuration and defaults
 ============================
 
@@ -60,13 +59,16 @@ Task result backend settings
         Use a relational database supported by the Django ORM.
 
     * cache
-        Use memcached to store the results.
+        Use `memcached`_ to store the results.
 
     * mongodb
-        Use MongoDB to store the results.
+        Use `MongoDB`_ to store the results.
+
+    * pyredis
+        Use `Redis`_ to store the results.
 
     * tyrant
-        Use Tokyo Tyrant to store the results.
+        Use `Tokyo Tyrant`_ to store the results.
 
     * amqp
         Send results back as AMQP messages
@@ -74,6 +76,13 @@ Task result backend settings
         try to receive the result once).
 
 
+.. _`memcached`: http://memcached.org
+.. _`MongoDB`: http://mongodb.org
+.. _`Redis`: http://code.google.com/p/redis/
+.. _`Tokyo Tyrant`: http://1978th.net/tokyotyrant/
+
+
+
 Database backend settings
 =========================
 
@@ -95,11 +104,12 @@ Example configuration
 
 .. code-block:: python
 
-    DATABASE_ENGINE="mysql"
-    DATABASE_USER="myusername"
-    DATABASE_PASSWORD="mypassword"
-    DATABASE_NAME="mydatabase"
-    DATABASE_HOST="localhost"
+    CELERY_BACKEND = "database"
+    DATABASE_ENGINE = "mysql"
+    DATABASE_USER = "myusername"
+    DATABASE_PASSWORD = "mypassword"
+    DATABASE_NAME = "mydatabase"
+    DATABASE_HOST = "localhost"
 
 Cache backend settings
 ======================
@@ -120,11 +130,11 @@ Using a single memcached server:
 
     CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
 
-
 Using multiple memcached servers:
 
 .. code-block:: python
 
+    CELERY_BACKEND = "cache"
     CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
 
 
@@ -134,7 +144,7 @@ Tokyo Tyrant backend settings
 **NOTE** The Tokyo Tyrant backend requires the :mod:`pytyrant` library:
     http://pypi.python.org/pypi/pytyrant/
 
-This backend requires the following configuration variables to be set:
+This backend requires the following configuration directives to be set:
 
 * TT_HOST
     Hostname of the Tokyo Tyrant server.
@@ -148,9 +158,57 @@ Example configuration
 
 .. code-block:: python
 
+    CELERY_BACKEND = "tyrant"
     TT_HOST = "localhost"
     TT_PORT = 1978
 
+Redis backend settings
+======================
+
+**NOTE** The Redis backend requires the :mod:`redis` library:
+    http://pypi.python.org/pypi/redis/0.5.5
+
+To install the redis package use ``pip`` or ``easy_install``::
+
+    $ pip install redis
+
+This backend requires the following configuration directives to be set:
+
+* REDIS_HOST
+
+    Hostname of the Redis database server. e.g. ``"localhost"``.
+
+* REDIS_PORT
+
+    Port to the Redis database server. e.g. ``6379``.
+
+Also, the following optional configuration directives are available:
+
+* REDIS_DB
+
+    Name of the database to use. Default is ``celery_results``.
+
+* REDIS_TIMEOUT
+
+    Timeout in seconds before we give up establishing a connection
+    to the Redis server.
+
+* REDIS_CONNECT_RETRY
+
+    Retry connecting if an connection could not be established. Default is
+    false.
+
+
+Example configuration
+---------------------
+
+.. code-block:: python
+
+    CELERY_BACKEND = "pyredis"
+    REDIS_HOST = "localhost"
+    REDIS_PORT = 6739
+    REDIS_DATABASE = "celery_results"
+    REDIS_CONNECT_RETRY=True
 
 MongoDB backend settings
 ========================
@@ -187,6 +245,7 @@ Example configuration
 
 .. code-block:: python
 
+    CELERY_BACKEND = "mongodb"
     CELERY_MONGODB_BACKEND_SETTINGS = {
         "host": "192.168.1.100",
         "port": 30000,
@@ -309,4 +368,3 @@ Process settings
 * CELERYD_PID_FILE
     Full path to the daemon pid file. Default is ``celeryd.pid``.
     Can be overridden using the ``--pidfile`` option to ``celeryd``.
-