"""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
Comments
I'm looking at line 32(?):
Combined with line 26, there could be some confusion about how long the delay is:
Right now the delay or stale period is going to be twice whatever MINT_DELAY is since you get
whenever you're in your refresh/stale condition.
Was that intended?
A fix in set() might be
#
No, the timeout sent to set() is the timeout for when it becomes stale. The +MINT_DELAY is when it really times out, for when the Django cache returns None.
The code is fine as is, you wouldn't give set timeout=MINT_DELAY unless you just wanted the timeout to be twice MINT_DELAY.
#
I wrote this code, and I think scelerat is right, but I could be wrong. Also, 'refreshed' should be renamed 'refreshing', and DEFAULT_TIMEOUT should be fetched from the CAHCE_BACKEND setting.
#
Anyway you should probably use django-newcache instead.
#