Stale-While-Revalidate Cache (Rust)
Topics: caching, background refresh, request coalescing, concurrency
Problem
Implement a stale-while-revalidate cache. Each entry is fresh for fresh, then stale for
a further stale window, then expired. The point: never block a caller on a refresh while a
usable value exists, and never stampede the origin (CDN/HTTP stale-while-revalidate).
pub struct Swr { /* … */ }
impl Swr {
pub fn new(fresh: Duration, stale: Duration,
load: impl Fn(&str) -> i32 + Send + Sync + 'static) -> Self;
pub fn get(&self, key: &str) -> i32;
pub fn wait(&self); // test helper: block until background refreshes finish
}
get(key):
- fresh → return the cached value; do not call
load.
- stale → return the stale value immediately, and trigger one background refresh for
that key (further stale gets while it runs do not start another — dedup).
- expired / missing → call
load synchronously, store, and return it.
Key concepts
- Two deadlines per entry:
fresh_until = now + fresh, stale_until = fresh_until + stale.
- Async revalidate: the stale path serves the old value and refreshes in a
thread, so the
caller never waits.
- Dedup: a
refreshing: HashSet ensures at most one in-flight refresh per key — the
thundering-herd guard.
inflight + Condvar: count background refreshes so wait can block until they finish (the
Mutex/Condvar pair stands in for a wait group).
The struct, new, store, and wait are provided; you implement get and spawn_refresh.
Grading
Your solution.rs is compiled together with a trusted tests.rs (which include!s it) using
rustc --test. Only solution.rs is yours to edit.
Sign in to submit your solution.