cache.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from datetime import timedelta
  2. from kombu.utils import partition
  3. from celery.backends.base import KeyValueStoreBackend
  4. from celery.exceptions import ImproperlyConfigured
  5. from celery.utils import timeutils
  6. from celery.datastructures import LocalCache
  7. def get_best_memcache(*args, **kwargs):
  8. behaviors = kwargs.pop("behaviors", None)
  9. is_pylibmc = False
  10. try:
  11. import pylibmc as memcache
  12. is_pylibmc = True
  13. except ImportError:
  14. try:
  15. import memcache
  16. except ImportError:
  17. raise ImproperlyConfigured("Memcached backend requires either "
  18. "the 'memcache' or 'pylibmc' library")
  19. client = memcache.Client(*args, **kwargs)
  20. if is_pylibmc and behaviors is not None:
  21. client.behaviors = behaviors
  22. return client
  23. class DummyClient(object):
  24. def __init__(self, *args, **kwargs):
  25. self.cache = LocalCache(5000)
  26. def get(self, key, *args, **kwargs):
  27. return self.cache.get(key)
  28. def set(self, key, value, *args, **kwargs):
  29. self.cache[key] = value
  30. def delete(self, key, *args, **kwargs):
  31. self.cache.pop(key, None)
  32. backends = {"memcache": get_best_memcache,
  33. "memcached": get_best_memcache,
  34. "pylibmc": get_best_memcache,
  35. "memory": DummyClient}
  36. class CacheBackend(KeyValueStoreBackend):
  37. _client = None
  38. def __init__(self, expires=None, backend=None, options={}, **kwargs):
  39. super(CacheBackend, self).__init__(self, **kwargs)
  40. self.expires = expires or self.app.conf.CELERY_TASK_RESULT_EXPIRES
  41. if isinstance(self.expires, timedelta):
  42. self.expires = timeutils.timedelta_seconds(self.expires)
  43. self.options = dict(self.app.conf.CELERY_CACHE_BACKEND_OPTIONS,
  44. **options)
  45. backend = backend or self.app.conf.CELERY_CACHE_BACKEND
  46. self.expires = int(self.expires)
  47. self.backend, _, servers = partition(backend, "://")
  48. self.servers = servers.split(";")
  49. try:
  50. self.Client = backends[self.backend]
  51. except KeyError:
  52. raise ImproperlyConfigured(
  53. "Unknown cache backend: %s. Please use one of the "
  54. "following backends: %s" % (self.backend,
  55. ", ".join(backends.keys())))
  56. def get(self, key):
  57. return self.client.get(key)
  58. def set(self, key, value):
  59. return self.client.set(key, value, self.expires)
  60. def delete(self, key):
  61. return self.client.delete(key)
  62. @property
  63. def client(self):
  64. if self._client is None:
  65. self._client = self.Client(self.servers, **self.options)
  66. return self._client