Expand description
Route-scoped response caching grammar (DW-037, feature analysis 5-Protocol “Response caching”): the config shape of a route’s cache policy and the compiled form the dataplane’s response cache consumes.
This is config-contract grammar in the same sense as transforms.rs
(DW-028) and versioning.rs (DW-048): validation
(snapshot::validate) and the runtime (dataplane::response_cache)
must agree on ONE parsing of these values, so the grammar lives in
config, the lowest consuming domain.
§Posture: explicit opt-in buffering, bounded
The dataplane buffers nothing by default; a cache entry is a
buffered response body. Presence of the cache block is therefore
the opt-in (the same presence-means-enabled rule as transforms,
compression, and masking), and the buffering is capped by
max_body_bytes per entry: a response that would cross the cap is
passed through UNSTORED and streams exactly as if no cache existed
(see dataplane::response_cache for the full cacheability matrix).
§Variance model: configured + policy-derived, not response-driven
RFC 9111 lets a response’s own Vary drive what a shared cache
keys on. dwara’s cache key must be derivable from the REQUEST alone
(the backing CacheStore extension trait is an opaque key-value
seam — no entry enumeration, so no
two-level “hash, then vary” lookup is possible). The variance
dimension is therefore DECLARED, not discovered:
- the operator lists extra request headers in
vary; - the snapshot compile folds in the headers the gateway’s own
policies already promise to vary by:
Acceptwhen the route selects onmatch.accept(DW-048),Originwhen the route carries a CORS policy (DW-027), andAccept-Encodingnever (cached bodies are identity; compression re-negotiates per request on replay).
A response whose Vary names anything OUTSIDE the effective set is
not stored (the cache cannot prove it would key correctly), and
Vary: * never stores. The union of everything the key folds in is
stamped on cached responses through the decoration tail’s existing
Vary merges, so replays advertise exactly what they varied by.
Structs§
- Compiled
Route Cache - The compiled per-route cache policy (DW-037): validated values
resolved into the exact durations, bounds, and the EFFECTIVE vary
set (configured entries plus the policy-derived
Accept/Originfolds), lowercased and in deterministic order. Built once at snapshot compile (RouteTable), never per request. - Route
Cache - Route-scoped response caching policy (DW-037). Absent (the
default): the route’s responses are never cached, buffered, or
stamped with cache headers — bytes flow exactly as before. Presence
opts the route’s GET traffic into the local response cache behind
the
CacheStoreextension seam (extensions domain). - Route
Cache Coalescing - Request-coalescing knobs (DW-038). Presence of the block on a
route’s
cacheis the opt-in (the same presence-means-enabled rule as every other block); this struct carries the one bound the behavior needs.
Constants§
- DEFAULT_
CACHE_ MAX_ BODY_ BYTES - Default
cache.max_body_bytes(DW-037): 1 MiB per entry — large enough for typical JSON payloads, small enough that a full store of them stays cheap. Validation bounds the configurable range around it. - DEFAULT_
COALESCE_ WAIT_ MS - Default
cache.coalescing.wait_ms(DW-038): 5 s — comfortably above a typical upstream fetch so a follower normally out-waits the leader instead of piling its own call on top (the wait bound exists for the pathological leader, not the common one). - MAX_
CACHE_ MAX_ BODY_ BYTES - Upper bound for
cache.max_body_bytes(DW-037): 16 MiB. A cache entry is a buffered body; the ceiling keeps one route’s policy from opting the gateway into buffering near-streaming payloads. - MAX_
CACHE_ STALE_ SECS - Upper bound for
cache.stale_while_revalidate_secs(DW-037): 24 hours, symmetric with the TTL bound. - MAX_
CACHE_ TTL_ SECS - Upper bound for
cache.ttl_secs(DW-037): 24 hours. Freshness beyond a day is an origin’s job (CDN), not a gateway’s local cache. - MAX_
CACHE_ VARY_ HEADERS - Maximum number of
varyentries (DW-037): the vary set multiplies the key space per route; eight extra dimensions is already generous. - MAX_
COALESCE_ WAIT_ MS - Upper bound for
cache.coalescing.wait_ms(DW-038): 60 s. A follower parked longer than a minute is a stuck request from the client’s point of view; the route’s own timeouts bound the leader, so a wait beyond them only delays the inevitable fail-open.
Functions§
- forbidden_
vary_ reason - Header names that may never appear in
cache.vary, with the reason validation reports. Checked case-insensitively against the lowercased name. Grammar helper in the house style ofnet.rs/transforms.rs: validation (snapshot) and compile agree on this one parsing.