MintCache (simple version)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
"""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

More like this

  1. MintCache by gfranxman 6 years, 1 month ago
  2. cache_smart template tag by michiel_1981 5 years, 3 months ago
  3. Run and cache only one instance of a heavy request by farnsworth 2 years, 9 months ago
  4. Effective content caching for mass-load site using redirect feature by nnseva 1 year, 10 months ago
  5. Safer cache key generation by cmheisel 4 years, 6 months ago

Comments

scelerat (on June 30, 2009):

I'm looking at line 32(?):

real_timeout = timeout + MINT_DELAY

Combined with line 26, there could be some confusion about how long the delay is:

set(key, val, timeout=MINT_DELAY, refreshed=True)

Right now the delay or stale period is going to be twice whatever MINT_DELAY is since you get

real_timeout = MINT_DELAY + MINT_DELAY

whenever you're in your refresh/stale condition.

Was that intended?

A fix in set() might be

if refreshed:
  real_timeout = timeout
else:
  real_timeout = timeout + MINT_DELAY

#

fahhem (on December 1, 2009):

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.

#

andrew (on July 29, 2010):

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.

#

andrew (on August 5, 2010):

Anyway you should probably use django-newcache instead.

#

(Forgotten your password?)