Alternatives: stale-while-revalidate (serve the stale value and refresh in the background with Celery), or refresh before expiry.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # ====================================================================== # Q: Implement cache-aside with protection from a stampede. # # Alternatives: stale-while-revalidate (serve the stale value and refresh in the # background with Celery), or refresh before expiry. # ====================================================================== def get_or_compute(key, compute, ttl=300): value = cache.get(key) if value is not None: return value # only one computes. cache.add is atomic (SET NX) if cache.add(f'{key}:lock', 1, timeout=30): try: value = compute() cache.set(key, value, ttl + random.randint(0, ttl // 10)) # jitter return value finally: cache.delete(f'{key}:lock') time.sleep(0.05) # the others wait a little return cache.get(key) or compute() |