Skip to content

Instantly share code, notes, and snippets.

@jacobb
Forked from noahsilas/gist:446050
Created June 20, 2010 22:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobb/446160 to your computer and use it in GitHub Desktop.
Save jacobb/446160 to your computer and use it in GitHub Desktop.
memcache_normal.py
"Memcached cache backend"
import time
from django.conf import settings
from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
from django.utils.encoding import smart_unicode, smart_str
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 = settings.CACHE_SETTINGS.get('binding', None)
if binding:
memcache = importlib.import_module(binding)
if hasattr(memcache, 'NotFound'):
self.LibraryValueNotFoundException = memcache.NotFound
else:
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 either the 'memcache' or 'cmemcache' library"
)
self._cache = memcache.Client(server.split(';'))
if hasattr(self._cache, 'behaviors'):
self._cache.behaviors = settings.CACHE_SETTINGS.get('behaviors', {})
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)
# python-memcache responds to incr on non-existent keys by
# raising a ValueError. Cmemcache returns None. In both
# cases, we should raise a ValueError though.
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)
# python-memcache responds to decr on non-existent keys by
# raising a ValueError. Cmemcache returns None. In both
# cases, we should raise a ValueError though.
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