Created
November 29, 2018 15:43
-
-
Save zoidyzoidzoid/f3988bb0202db45451ad3e1365a4117e to your computer and use it in GitHub Desktop.
Revisions
-
zoidyzoidzoid created this gist
Nov 29, 2018 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,67 @@ import pickle import time from django.core.cache.backends.base import DEFAULT_TIMEOUT from django.core.cache.backends.memcached import MemcachedCache as _Cache try: import memcache except ImportError: _MintCache = None else: class _MintCache(_Cache): _cache = None "Memcached cache backend the sequel." def __init__(self, server, params): super(_MintCache, self).__init__(self, params) self._client = memcache.Client(server.split(';')) def get(self, key, default=None, version=None): """Fetch value, and if it's gonna expire soon, refresh it. This has a race condition, since all requests that happen after stale_after during the first client refreshing it will also try refresh it. We should set a refreshing-{key} key in the cache for the first client that is refreshing, ensuring that only one client tries to refresh the key at a time. """ key = self.make_key(key, version=version) val = self._cache.get(key) lease_key = 'refreshing-{}'.format(key) lease = self._cache.gets(lease_key) if val is None: val = default else: try: stale_after, val = pickle.loads(val) now = time.time() if now > stale_after: if lease: # We're already refreshing the key, so let's # return the stale value val = default else: # cache_log("stale, getting lease") # Try set lease key, but if another client has # fetched the lease return default got_lease = self._cache.cas(lease_key, 1, 60) if got_lease: self.set(key, val, 60) val = default except: pass return val def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): key = self.make_key(key, version=version) if timeout is 0: timeout = self.default_timeout now = time.time() val = pickle.dumps((now + timeout, value), 2) self._cache.set(key, val, 7*86400) def delete(self, key, version=None): key = self.make_key(key, version=version) self._cache.delete(key)