cache.py 2.4 KB

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