"""Wrapper functions around Django's core cache to implement stale-while-revalidating cache. Has the standard Django cache interface. The timeout passed to ``set'' is the time at which the cache will be revalidated; this is different from the built-in cache behavior because the object will still be available from the cache for MINT_DELAY additional seconds. """ import time from django.core.cache import cache # MINT_DELAY is an upper bound on how long any value should take to # be generated (in seconds) MINT_DELAY = 30 DEFAULT_TIMEOUT = 300 def get(key): packed_val = cache.get(key) if packed_val is None: return None val, refresh_time, refreshed = packed_val if (time.time() > refresh_time) and not refreshed: # Store the stale value while the cache revalidates for another # MINT_DELAY seconds. set(key, val, timeout=MINT_DELAY, refreshed=True) return None return val def set(key, val, timeout=DEFAULT_TIMEOUT, refreshed=False): refresh_time = timeout + time.time() real_timeout = timeout + MINT_DELAY packed_val = (val, refresh_time, refreshed) return cache.set(key, packed_val, real_timeout) delete = cache.delete