Proxy: control access to a helper
Picture
A slow lookup returns the same value repeatedly. A cache proxy can answer a hit without reaching the underlying source.
Predict
Can this forever-cache safely wrap arbitrary changing data?
Walk through the small example
No, it needs a freshness policy. Interface compatibility does not remove the risk of stale answers.
Mental model and complete Python solution
A proxy controls access to a subject while exposing the same operation. Caching, authorization, and lazy initialization are common motives. The example stores values only after successful source calls, so failures do not become cached success. A dictionary membership test distinguishes a cached None from a miss. This unbounded cache is deliberately for a finite immutable dataset.
What the function promises: Source values are immutable for the proxy’s lifetime. get may return None as a valid value and propagates source errors. No concurrency or eviction policy is included.
class MappingSource:
def __init__(self, values):
self.values, self.calls = dict(values), 0
def get(self, key):
self.calls += 1
return self.values[key]
class CacheProxy:
def __init__(self, source):
self.source, self.cache = source, {}
def get(self, key):
if key not in self.cache:
self.cache[key] = self.source.get(key)
return self.cache[key]
source = MappingSource({"a": None})
proxy = CacheProxy(source)
assert proxy.get("a") is None and proxy.get("a") is None
assert source.calls == 1
Work and storage: Expected O(1) cache hits, source cost on misses, and O(number of cached keys) storage.
When to recognize it: Our example caches immutable values only. Mutable data would need expiry, invalidation, or a version-aware key.
Check before applying it: Caching changes freshness and concurrency behavior. A proxy must state those changes clearly.
Change one rule
Two callers miss the same expensive key simultaneously. Does a cache by itself prevent duplicate work?
See what changes
No. Consider a per-key in-flight request or single-flight mechanism, with timeout and failure cleanup. A global lock may unnecessarily serialize unrelated keys.
Connect
LRU Cache: Cache storage needs an eviction and consistency invariant.
Keep a nearby copy with an expiry story: Move the same freshness questions across a network boundary.