pub struct InProcessTtlCache { /* private fields */ }Expand description
In-process TTL cache backing the super::Cache port. Per-pod —
cross-pod convergence happens at TTL expiry, NOT via shared
substrate. Default for RCW/CTW Slice 4/5 wiring (RFC §3.5 Row 5*).
§TTL semantics
Entries are evicted lazily: a get past inserted_at + ttl returns
None and removes the row. There is no background reaper; memory
reclamation happens at next access. For pre-launch workloads with
bounded user counts this is appropriate; production hot-paths with
millions of unique subs should swap in a bounded-capacity Cache impl
(e.g. an LRU). The capacity question is intentionally NOT folded
into this struct — STANDARDS_SHARED_CACHE.md §3.1 documents the
canonical key shape, and bounded-capacity is a substrate concern
not visible at the port surface.
§Concurrency
RwLock<HashMap> — reads scale; writes serialize. Under sv-axis
load profile (95%+ cache hits past warmup, writes only on miss),
the lock split is well-suited.
§Why not shared KVRocks
Shared KVRocks (STANDARDS_SHARED_CACHE.md §3.1) is the textbook
chat-as-infrastructure substrate — sub-millisecond reads,
real-time cross-pod convergence, single canonical write site (PAS
on break-glass). 11.Z deliberately defers KVRocks ACL extension to
RCW/CTW (per user direction 2026-05-09). Wiring is a one-line
Arc<dyn Cache> swap when ACL extends in 11.AB+.
Implementations§
Source§impl InProcessTtlCache
impl InProcessTtlCache
Sourcepub fn new(ttl: Duration) -> Self
pub fn new(ttl: Duration) -> Self
Build with the specified TTL. Use super::SV_CACHE_TTL
(re-exported from ppoppo-token, currently 60 seconds) to match
the canonical sv:{sub} cache contract.
pub fn with_clock(self, clock: ArcClock) -> Self
Trait Implementations§
Source§impl Cache for InProcessTtlCache
impl Cache for InProcessTtlCache
Source§fn get<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Option<i64>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Option<i64>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn set<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
sv: i64,
_ttl: Duration,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn set<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
sv: i64,
_ttl: Duration,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
ttl (Redis SETEX, KVRocks TTL, in-process
expiration). Failures are swallowed — the next call will fetch
again.