backend.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. from threading import local
  2. from collections import namedtuple
  3. from django.core.cache import CacheHandler
  4. _getitem = CacheHandler.__getitem__
  5. def patch_cache_handler():
  6. _caches_cls = namedtuple("_caches", ["caches"])
  7. def __getitem__(self, alias):
  8. if isinstance(self._caches, local):
  9. self._caches = _caches_cls(getattr(self._caches, "caches", {}))
  10. return _getitem(self, alias)
  11. CacheHandler.__getitem__ = __getitem__
  12. try:
  13. import cPickle as pickle
  14. except ImportError:
  15. import pickle
  16. from . import client
  17. from django.core.cache.backends.memcached import BaseMemcachedCache
  18. def serialize_pickle(key, value):
  19. if type(value) == bytes:
  20. return value, 1
  21. elif type(value) == int:
  22. return value, 3
  23. return pickle.dumps(value), 2
  24. def deserialize_pickle(key, value, flags):
  25. if flags == 1:
  26. return value
  27. if flags == 3:
  28. return int(value)
  29. if flags == 2:
  30. return pickle.loads(value)
  31. raise Exception('Unknown flags for value: {1}'.format(flags))
  32. class PyMemcacheCache(BaseMemcachedCache):
  33. """An implementation of a cache binding using pymemcache."""
  34. def __init__(self, server, params):
  35. BaseMemcachedCache.__init__(
  36. self,
  37. server,
  38. params,
  39. library=client,
  40. value_not_found_exception=ValueError
  41. )
  42. self._client = None
  43. @property
  44. def _cache(self):
  45. if not self._client:
  46. kwargs = {
  47. 'serializer': serialize_pickle,
  48. 'deserializer': deserialize_pickle,
  49. }
  50. if self._options:
  51. for key, value in self._options.items():
  52. kwargs[key.lower()] = value
  53. # default use_pooling
  54. if "use_pooling" not in kwargs:
  55. kwargs["use_pooling"] = True
  56. if "ignore_exc" not in kwargs:
  57. kwargs["ignore_exc"] = True
  58. servers = []
  59. for server in self._servers:
  60. host, port = server.split(":")
  61. servers.append((host, int(port)))
  62. self._client = self._lib.Client(servers, **kwargs)
  63. if self._client.use_pooling:
  64. patch_cache_handler()
  65. return self._client