CacheStack
A CacheStack allows combining multiple caches into a single prioritized hierarchy. It is a common pattern to combine a fast, local cache (like an in-memory cache) with a larger, slower, and potentially remote cache (like a database or file system).
Automatic Hit Transfer
Whenever a hit is found in a higher-level cache, it is automatically transferred to the base cache (index 0). This ensures that frequently accessed data migrates to the fastest cache in your stack.
[1]:
import tempfile
import os
from fleche import fleche, cache
from fleche.caches import Cache, CacheStack
from fleche.storage import Memory, PickleFile
from fleche.storage.sql import Sql
# 1. Setup a 'remote' persistent cache
tmp_dir = tempfile.TemporaryDirectory()
# Use PickleFile for values and Sql for calls to simulate a robust remote storage
remote_storage_values = PickleFile.with_cloudpickle(tmp_dir.name)
remote_storage_calls = Sql(f"sqlite:///{os.path.join(tmp_dir.name, 'cache.db')}")
remote_cache = Cache(remote_storage_values, remote_storage_calls)
# 2. Setup a 'local' fast memory cache
local_cache = Cache(Memory({}), Memory({}))
@fleche
def expensive_computation(x):
print(f"Computing {x}...")
return x * 10
# Pre-populate the remote cache
with cache(remote_cache):
expensive_computation(42)
print("Remote cache contains 42:", remote_cache.contains(expensive_computation.digest(42)))
print("Local cache contains 42: ", local_cache.contains(expensive_computation.digest(42)))
No config file found. Using default memory cache.
Computing 42...
Remote cache contains 42: True
Local cache contains 42: False
Creating the stack
We prioritize local_cache over remote_cache by putting it at the front of the stack.
[2]:
stack = CacheStack((local_cache, remote_cache))
with cache(stack):
# Loading 42 will hit remote_cache and automatically transfer it to local_cache
print("Calling expensive_computation(42) via stack...")
result = expensive_computation(42)
print(f"Result: {result}")
print("Local cache now contains 42:", local_cache.contains(expensive_computation.digest(42)))
# Cleanup
tmp_dir.cleanup()
Calling expensive_computation(42) via stack...
Result: 420
Local cache now contains 42: True