Kistaro icon

Reader/writer lazy cache fill algorithm

Kistaro | PRO | 02/12/18 06:17:31 PM UTC | 0 ⭐ | 263 👁️ | Never ⏰ | []
Python |

1.3 KB

|

None

|

0 👍

/

0 👎

with cache_lock.reader_lock:
    x = cache_fetch_under_rlock(params)
    if x is not None:
        return x
 
# cache miss; must populate
with cache_lock.writer_lock:
    x = cache_fetch_under_rlock(params)
    if x is not None:
        # oops, we didn't need to write, oh well
        return x
    x = do_the_expensive_thing(params)
    cache_write_under_wlock(params, x)
    return x
    
# do_the_expensive_thing may repeat this pattern with a different lock,
# if it has its own cache or pipelined single source of truth. This
# is a nestable, generic pattern for maximizing cache throughput
# while provably not duplicating the expensive thing. It has the
# disadvantage of holding the cache lock for the entire Expensive Thing
# but this is often appropriate; if it is worse to unnecessarily hold
# the writer lock than it is to duplicate work, however...
 
with cache_lock.reader_lock:
    x = cache_fetch_under_rlock(params)
    if x is not None:
        return x
 
z = do_the_expensive_thing(params)
 
with cache_lock.writer_lock:
    x = cache_fetch_under_rlock(params)
    if x is not None:
        # oops
        return x  # it is more GC-memory-efficient to throw z away;
                  # under garbage collection, prefer old objects
    cache_write_under_wlock(params, z)
    return z

Comments