pas_external/epoch/cache.rs
1//! [`Cache`] port — best-effort `sv:{sub}` cache.
2
3use std::time::Duration;
4
5use async_trait::async_trait;
6
7/// Best-effort cache of `sv:{sub}` values.
8///
9/// Promoted to the SDK in Phase 11.Z from chat-auth's private
10/// `SessionVersionCache` trait (§3 Row 6 "replace, don't layer"). The
11/// shape is identical: `get` returns `None` on miss OR transient cache
12/// error; the [`super::CompositeEpochRevocation`] composer falls
13/// through to its [`super::Fetcher`] in either case, so `Cache` impls
14/// don't expose error variants. `set` is best-effort and swallows
15/// failures internally — a failed write only means the next call will
16/// fetch again.
17///
18/// `key` is the full `sv:{sub}` form (built via
19/// [`super::sv_cache_key`]) so the SDK port matches the canonical
20/// PAS↔consumer shared-cache contract documented in
21/// `STANDARDS_SHARED_CACHE.md` §3.1.
22///
23/// ## Implementations
24///
25/// - [`super::InProcessTtlCache`] — opinionated per-pod TTL map; default
26/// wiring for RCW/CTW (Slice 4/5).
27/// - chat-auth-internal — KVRocks-backed reader (kept consumer-side
28/// because it depends on `ppoppo-kvrocks`, which is not in the SDK
29/// feature graph).
30/// - 11.AB+ — SDK ships a KVRocks-backed `Cache` once
31/// `KVROCKS_URL` ACL extends to RCW/CTW.
32#[async_trait]
33pub trait Cache: Send + Sync {
34 /// Look up the cached `sv` for `key` (`"sv:{sub}"`).
35 ///
36 /// Returns `None` on miss OR transient cache error — the composer
37 /// treats both identically (fall through to the authoritative
38 /// fetcher), so callers don't need separate error handling for
39 /// cache unavailability.
40 async fn get(&self, key: &str) -> Option<i64>;
41
42 /// Best-effort write-back after a successful fetch. Implementations
43 /// SHOULD honor the `ttl` (Redis `SETEX`, KVRocks TTL, in-process
44 /// expiration). Failures are swallowed — the next call will fetch
45 /// again.
46 async fn set(&self, key: &str, sv: i64, ttl: Duration);
47}