|
@@ -3,6 +3,7 @@ from datetime import timedelta
|
|
|
from celery.backends.base import KeyValueStoreBackend
|
|
|
from celery.exceptions import ImproperlyConfigured
|
|
|
from celery.utils import timeutils
|
|
|
+from celery.utils import cached_property
|
|
|
|
|
|
try:
|
|
|
import redis
|
|
@@ -13,31 +14,26 @@ except ImportError:
|
|
|
|
|
|
|
|
|
class RedisBackend(KeyValueStoreBackend):
|
|
|
- """Redis based task backend store.
|
|
|
+ """Redis task result store."""
|
|
|
|
|
|
- .. attribute:: redis_host
|
|
|
-
|
|
|
- The hostname to the Redis server.
|
|
|
-
|
|
|
- .. attribute:: redis_port
|
|
|
-
|
|
|
- The port to the Redis server.
|
|
|
-
|
|
|
- Raises :class:`celery.exceptions.ImproperlyConfigured` if
|
|
|
- the :setting:`REDIS_HOST` or :setting:`REDIS_PORT` settings is not set.
|
|
|
-
|
|
|
- """
|
|
|
+ #: redis-py client module.
|
|
|
redis = redis
|
|
|
+
|
|
|
+ #: default Redis server hostname (`localhost`).
|
|
|
redis_host = "localhost"
|
|
|
+
|
|
|
+ #: default Redis server port (6379)
|
|
|
redis_port = 6379
|
|
|
redis_db = 0
|
|
|
+
|
|
|
+ #: default Redis password (:const:`None`)
|
|
|
redis_password = None
|
|
|
|
|
|
def __init__(self, redis_host=None, redis_port=None, redis_db=None,
|
|
|
redis_password=None,
|
|
|
expires=None, **kwargs):
|
|
|
super(RedisBackend, self).__init__(**kwargs)
|
|
|
- if redis is None:
|
|
|
+ if self.redis is None:
|
|
|
raise ImproperlyConfigured(
|
|
|
"You need to install the redis library in order to use "
|
|
|
+ "Redis result store backend.")
|
|
@@ -61,48 +57,34 @@ class RedisBackend(KeyValueStoreBackend):
|
|
|
self.expires = timeutils.timedelta_seconds(self.expires)
|
|
|
if self.expires is not None:
|
|
|
self.expires = int(self.expires)
|
|
|
+ self.redis_port = int(self.redis_port)
|
|
|
|
|
|
- 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")
|
|
|
- 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 = self.redis.Redis(host=self.redis_host,
|
|
|
- port=self.redis_port,
|
|
|
- db=self.redis_db,
|
|
|
- password=self.redis_password)
|
|
|
- return self._connection
|
|
|
+ def get(self, key):
|
|
|
+ return self.client.get(key)
|
|
|
+
|
|
|
+ def set(self, key, value):
|
|
|
+ client = self.client
|
|
|
+ client.set(key, value)
|
|
|
+ if self.expires is not None:
|
|
|
+ client.expire(key, self.expires)
|
|
|
+
|
|
|
+ def delete(self, key):
|
|
|
+ self.client.delete(key)
|
|
|
|
|
|
def close(self):
|
|
|
- """Close the connection to redis."""
|
|
|
- if self._connection is not None:
|
|
|
- self._connection.connection.disconnect()
|
|
|
- self._connection = None
|
|
|
+ """Closes the Redis connection."""
|
|
|
+ del(self.client)
|
|
|
|
|
|
def process_cleanup(self):
|
|
|
self.close()
|
|
|
|
|
|
- def get(self, key):
|
|
|
- return self.open().get(key)
|
|
|
+ @cached_property
|
|
|
+ def client(self):
|
|
|
+ return self.redis.Redis(host=self.redis_host,
|
|
|
+ port=self.redis_port,
|
|
|
+ db=self.redis_db,
|
|
|
+ password=self.redis_password)
|
|
|
|
|
|
- def set(self, key, value):
|
|
|
- r = self.open()
|
|
|
- r.set(key, value)
|
|
|
- if self.expires is not None:
|
|
|
- r.expire(key, self.expires)
|
|
|
-
|
|
|
- def delete(self, key):
|
|
|
- self.open().delete(key)
|
|
|
+ @client.deleter
|
|
|
+ def client(self, client):
|
|
|
+ client.connection.disconnect()
|