Created
June 20, 2010 19:50
-
-
Save noahsilas/446050 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"Memcached cache backend" | |
import time | |
from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError | |
from django.utils.encoding import smart_unicode, smart_str | |
from django.utils import importlib | |
class CacheClass(BaseCache): | |
def __init__(self, server, params): | |
BaseCache.__init__(self, params) | |
# The exception type to catch from the underlying library for a key | |
# that was not found. This is a ValueError for python-memcache, | |
# pylibmc.NotFound for pylibmc, and cmemcache will return None without | |
# raising an exception. | |
self.LibraryValueNotFoundException = ValueError | |
binding = params.get('binding', None) | |
if binding: | |
memcache = importlib.import_module(binding) | |
if hasattr(memcache, 'NotFound'): | |
self.LibraryValueNotFoundException = memcache.NotFound | |
else: | |
# use fallbacks for backwards compatibility | |
try: | |
import cmemcache as memcache | |
import warnings | |
warnings.warn( | |
"Support for the 'cmemcache' library has been deprecated. Please use python-memcached instead.", | |
DeprecationWarning | |
) | |
except ImportError: | |
try: | |
import memcache | |
except: | |
raise InvalidCacheBackendError( | |
"Memcached cache backend requires the 'memcache', the 'cmemcache' library, or a specified binding." | |
) | |
self._cache = memcache.Client(server.split(';')) | |
if hasattr(self._cache, 'behaviors'): | |
for k, v in params.items(): | |
if k == 'binding': | |
continue | |
self._cache.behaviors[k] = v | |
def _get_memcache_timeout(self, timeout): | |
""" | |
Memcached deals with long (> 30 days) timeouts in a special | |
way. Call this function to obtain a safe value for your timeout. | |
""" | |
timeout = timeout or self.default_timeout | |
if timeout > 2592000: # 60*60*24*30, 30 days | |
# See http://code.google.com/p/memcached/wiki/FAQ | |
# "You can set expire times up to 30 days in the future. After that | |
# memcached interprets it as a date, and will expire the item after | |
# said date. This is a simple (but obscure) mechanic." | |
# | |
# This means that we have to switch to absolute timestamps. | |
timeout += int(time.time()) | |
return timeout | |
def add(self, key, value, timeout=0): | |
if isinstance(value, unicode): | |
value = value.encode('utf-8') | |
return self._cache.add(smart_str(key), value, self._get_memcache_timeout(timeout)) | |
def get(self, key, default=None): | |
val = self._cache.get(smart_str(key)) | |
if val is None: | |
return default | |
return val | |
def set(self, key, value, timeout=0): | |
self._cache.set(smart_str(key), value, self._get_memcache_timeout(timeout)) | |
def delete(self, key): | |
self._cache.delete(smart_str(key)) | |
def get_many(self, keys): | |
return self._cache.get_multi(map(smart_str,keys)) | |
def close(self, **kwargs): | |
self._cache.disconnect_all() | |
def incr(self, key, delta=1): | |
try: | |
val = self._cache.incr(key, delta) | |
except self.LibraryValueNotFoundException: | |
val = None | |
if val is None: | |
raise ValueError("Key '%s' not found" % key) | |
return val | |
def decr(self, key, delta=1): | |
try: | |
val = self._cache.decr(key, delta) | |
except self.LibraryValueNotFoundException: | |
val = None | |
if val is None: | |
raise ValueError("Key '%s' not found" % key) | |
return val | |
def set_many(self, data, timeout=0): | |
safe_data = {} | |
for key, value in data.items(): | |
if isinstance(value, unicode): | |
value = value.encode('utf-8') | |
safe_data[smart_str(key)] = value | |
self._cache.set_multi(safe_data, self._get_memcache_timeout(timeout)) | |
def delete_many(self, keys): | |
self._cache.delete_multi(map(smart_str, keys)) | |
def clear(self): | |
self._cache.flush_all() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment