pub struct ResponseCache { /* private fields */ }Expand description
The local response cache: opaque store + route epochs + the
single-flight revalidation guard + the request-coalescing leader
map. Owned by the DataPlane; survives reloads.
Implementations§
Source§impl ResponseCache
impl ResponseCache
Sourcepub fn new(store: Arc<dyn CacheStore>) -> Self
pub fn new(store: Arc<dyn CacheStore>) -> Self
Build over a specific backend (tests inject the plain in-memory store; the OSS gateway uses the moka backend).
Sourcepub fn set_store(&self, store: Arc<dyn CacheStore>)
pub fn set_store(&self, store: Arc<dyn CacheStore>)
Swap the backing store (SCALE-04, #183). Called at startup when
a Redis cache config is present and the license grants the
redis_cache feature claim. The old store’s entries are NOT
migrated (the new store starts cold; a two-tier CoordinatedCache
fronts Redis with the local moka cache so hot keys survive).
Sourcepub fn store_handle(&self) -> Arc<dyn CacheStore>
pub fn store_handle(&self) -> Arc<dyn CacheStore>
Clone of the backing store Arc (admin/metrics introspection seam).
Sourcepub fn live_entries(&self) -> i64
pub fn live_entries(&self) -> i64
Approximate live entries (the dwara_cache_entries gauge walk;
0 when the backend cannot report).
Sourcepub fn purge_count(&self) -> u64
pub fn purge_count(&self) -> u64
Purges + epoch bumps performed since process start.
Sourcepub fn epoch(&self, route: &str) -> u64
pub fn epoch(&self, route: &str) -> u64
The route’s current cache epoch (0 for never-bumped routes).
Sourcepub fn bump_route(&self, route: &str) -> u64
pub fn bump_route(&self, route: &str) -> u64
Advance one route’s epoch (admin purge, DW-037). Every entry stored under an earlier epoch is unreachable from the next lookup — O(1), no store enumeration, which is the whole point.
Sourcepub fn purge_all(&self, route_names: impl IntoIterator<Item = String>) -> usize
pub fn purge_all(&self, route_names: impl IntoIterator<Item = String>) -> usize
Purge every named route at once (admin purge-all): bumps each CURRENT route’s epoch (routes no longer in the config have no reachable entries). Returns how many routes were invalidated.
Sourcepub async fn purge_by_tag(&self, tag: &str) -> usize
pub async fn purge_by_tag(&self, tag: &str) -> usize
Purge every entry tagged with tag (DP-04). The tag’s keys are
deleted from the store and the tag’s index entry is cleared.
Returns the number of keys the tag mapped to (a tag with no
entries, or one the gateway never saw, returns 0). Unlike the
epoch-based route purge this is an O(keys-with-tag) store
deletion — the tag index is the only place the opaque
CacheStore seam exposes which keys carry a tag.
Sourcepub async fn purge_by_url(&self, url: &str, prefix: bool) -> usize
pub async fn purge_by_url(&self, url: &str, prefix: bool) -> usize
Purge every entry whose request URL matches (DP-04). With
prefix false the URL must match exactly (path[?query]); with
prefix true every URL whose path starts with prefix as a path
segment is purged (e.g. /api/users/ evicts every user entry;
/api/users evicts /api/users, /api/users/123, and
/api/users?x=1 but NOT /api/users2). Returns the number of
keys deleted. The URL index maps one URL to many keys (the cache
key also folds the route epoch, the consumer, and the vary
values), so a single URL purge can delete several entries.
Sourcepub fn note_generation(&self, old: Option<&Snapshot>, fresh: &Snapshot)
pub fn note_generation(&self, old: Option<&Snapshot>, fresh: &Snapshot)
Generation-change invalidation (called from
DataPlane::refresh before the swap): a route whose
definition CHANGED (Route equality — masking, transforms, the
cache block itself, anything) has its epoch bumped, because its
stored bytes were shaped by the old definition. Unchanged
routes keep their entries warm; removed routes bump once so a
later same-name re-add cannot inherit them.
Sourcepub async fn lookup(
self: &Arc<Self>,
dp: &Arc<DataPlane>,
policy: &Arc<CompiledRouteCache>,
route: &Route,
identity: Option<&Identity>,
peer: IpAddr,
path: &str,
query: Option<&str>,
req_headers: &HeaderMap,
method: &Method,
declared_body_bytes: Option<u64>,
obs: &Observability,
) -> LookupOutcome
pub async fn lookup( self: &Arc<Self>, dp: &Arc<DataPlane>, policy: &Arc<CompiledRouteCache>, route: &Route, identity: Option<&Identity>, peer: IpAddr, path: &str, query: Option<&str>, req_headers: &HeaderMap, method: &Method, declared_body_bytes: Option<u64>, obs: &Observability, ) -> LookupOutcome
The lookup half of the cache (DW-037), running after authn/
authz/rate limiting/admission and before the proxy action.
See the module docs for the cacheability rules and the key
derivation; this function only classifies and either replays or
hands a MissFlow to the store stage.
Sourcepub async fn store_stage(
&self,
flow: CacheFlow,
resp: Response<ProxyBody>,
rid: &str,
obs: &Observability,
) -> Response<ProxyBody>
pub async fn store_stage( &self, flow: CacheFlow, resp: Response<ProxyBody>, rid: &str, obs: &Observability, ) -> Response<ProxyBody>
The store half of the cache (DW-037), running after masking and
the DW-028 transforms and before compression. Stamps the
x-cache outcome on the response in every arm. See the module
docs for the response-side storable rules.
Sourcepub async fn attach(
&self,
flow: &MissFlow,
obs: &Observability,
) -> CoalesceOutcome
pub async fn attach( &self, flow: &MissFlow, obs: &Observability, ) -> CoalesceOutcome
Request coalescing (DW-038): resolve ONE cache miss into the
leader, a served follower, or an independent fetch. The
coalescing key is the cache key itself (route epoch, consumer,
path, query, vary — see derive_key), so a follower can only
be handed an outcome computed for an identical request shape of
its own consumer and generation. The caller runs its fetch on
Lead/Solo and drops the guard when its store stage is done.
Follower resolution, in the pinned order: (1) wait, bounded by
the route’s coalescing.wait_ms; (2) epoch check FIRST — a
mid-flight purge/config change detours to an independent fetch
even if the leader stored something; (3) store re-read — a live
entry replays exactly like a hit; (4) otherwise an independent
fetch (leader finished unstored, or the wait expired). Every
fallback is the caller’s NORMAL miss path: failures are never
inherited, and each fetching follower runs the route’s full
retry policy.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for ResponseCache
impl !RefUnwindSafe for ResponseCache
impl Send for ResponseCache
impl Sync for ResponseCache
impl Unpin for ResponseCache
impl !UnwindSafe for ResponseCache
Blanket Implementations§
§impl<T> AnyExt for T
impl<T> AnyExt for T
§fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
T behind reference§fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
T behind mutable reference§fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
T behind Rc pointer§fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
T behind Arc pointer§fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
T behind Box pointer§fn downcast_move<T>(this: Self) -> Option<T>
fn downcast_move<T>(this: Self) -> Option<T>
Self to T,
useful only in generic context as a workaround for specializationSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
fn coerce_rc_to(self: Rc<X>) -> Rc<T>
fn coerce_box_to(self: Box<X>) -> Box<T>
fn coerce_ref_to(&self) -> &T
fn coerce_mut_to(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more