107 lines
7.9 KiB
Markdown
107 lines
7.9 KiB
Markdown
# RustProxy 0.22.0 specification audit
|
|
|
|
This audit maps the 0.22 cache work directly to the requested scope. The implementation status below is based on the current source tree. Rust unit/integration tests are present, but this packaging workspace has no `cargo`, `rustc` or `rustfmt`; compiler/runtime acceptance therefore remains open until the release-host gate runs.
|
|
|
|
## P0 - request collapsing / cache stampede protection
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| Per-cache-key lock / single-flight | IMPLEMENTED | `src/cache/collapse.rs` tracks one foreground fill flight per primary cache key. |
|
|
| First request fills, followers wait | IMPLEMENTED | Leader owns `FillLeaderGuard`; followers await the retained completion state. |
|
|
| Wait timeout | IMPLEMENTED | `cache.collapse_wait_timeout_ms`, validated to 10..60000 ms. |
|
|
| Controlled timeout fallback | IMPLEMENTED | `cache.collapse_timeout_fallback`: origin or stale-if-available. |
|
|
| Release on error/cancel | IMPLEMENTED | Guard `Drop` removes the flight and publishes completion even after purge cancellation. |
|
|
| SWR integration | IMPLEMENTED | Foreground collapsing is separate from and compatible with the existing background-revalidation dedupe. |
|
|
| Metrics | IMPLEMENTED | Collapsed fills, timeouts and current waiters are exposed in cache metrics. |
|
|
| Concurrent MISS/variant regressions | SOURCE-TESTED | Rust tests cover wait-until-publish, timeout/leader drop, cancelled-follower metric cleanup and retry after a different `Vary` representation wins the first fill. |
|
|
|
|
## P1 - Range / HTTP 206
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| `Range: bytes=...` | IMPLEMENTED | One byte range, including bounded, open-ended and suffix forms. |
|
|
| `206 Partial Content` | IMPLEMENTED | Local cache slicing returns 206 with exact body length. |
|
|
| `Content-Range` / `Accept-Ranges` | IMPLEMENTED | Emitted for satisfiable cached ranges; unsatisfied ranges return 416 with `bytes */len`. |
|
|
| `If-Range` | IMPLEMENTED | Strong ETag and HTTP-date handling; weak validators do not match. |
|
|
| One range without full response buffering | IMPLEMENTED | Cache HIT slices the already-complete cached object; origin Range responses remain streamed. |
|
|
| Multipart decision | DEFINED | Multipart/multiple/unsupported Range forms are passed through to origin and are not synthesized or cached as separate range objects. |
|
|
| Compression/transform policy | DEFINED | Origin Range path requests identity encoding and skips transformation/client compression; local range is cut from the canonical complete cached representation. |
|
|
| Cache HIT + Range without origin | IMPLEMENTED | Complete cached representation serves the requested single range directly. |
|
|
| Preserve validators/Age | IMPLEMENTED | Cached range response retains cache validators and cache Age; only range framing/length/status is rewritten. |
|
|
| Revalidation + Range | IMPLEMENTED | A stale complete object revalidated by origin 304 is then evaluated again for 206/416/If-Range behavior. |
|
|
| Range regressions | SOURCE-TESTED | Rust tests cover 206, suffix/open-ended ranges, 416, validators, `If-Range`, duplicate fields and multipart rejection. |
|
|
|
|
## P2 - extended stale-if-error policy
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| Timeout / connection / DNS / TLS classes | IMPLEMENTED | Independent booleans select eligible transport failure classes. |
|
|
| Optional HTTP status list | IMPLEMENTED | `stale_if_error_statuses`, max 32 unique 5xx values; default `500,502,503,504`. |
|
|
| Backward-compatible default | IMPLEMENTED | Default transport classes remain enabled and the previous 5xx set is preserved. |
|
|
| Regression coverage | SOURCE-TESTED | Policy test covers class/status inclusion and exclusion; existing RFC 5861 window tests remain. |
|
|
|
|
## P2 - proactive cache refresh
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| Threshold before expiry | IMPLEMENTED | `proactive_refresh_before_expiry_seconds`. |
|
|
| Limit fraction without traffic | IMPLEMENTED | Deterministic `proactive_refresh_percent` sampling, default disabled. |
|
|
| Reuse existing revalidation | IMPLEMENTED | Reuses validator-based `refresh_cache_once` and background-revalidation guard. |
|
|
| Avalanche protection | IMPLEMENTED | Per-key schedule dedupe plus `proactive_refresh_max_inflight`; a just-filled object can schedule refresh without another client request. |
|
|
| Regression coverage | SOURCE-TESTED | Guard test covers schedule dedupe and global concurrency limit. |
|
|
|
|
## P1 - selective Cache PURGE / BAN
|
|
|
|
### PURGE
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| Exact URL | IMPLEMENTED | Exact path/query or absolute URL selector. |
|
|
| Host + URL | IMPLEMENTED | Optional host/authority filter combines with exact/prefix/pattern selection. |
|
|
| URL prefix | IMPLEMENTED | Prefix matches the actual request target, including query text. |
|
|
| Cache key | IMPLEMENTED | Exact 64-hex primary cache key selector. |
|
|
| Cache tag | IMPLEMENTED | `Cache-Tag` values are parsed/stored and can be purged by tag. |
|
|
| Regex/pattern | IMPLEMENTED | Rust `regex` engine with 512-character input bound and 1 MiB compiled-size bound; every regex purge/BAN requires explicit broad-operation confirmation. |
|
|
| RAM + persistent/cold | IMPLEMENTED | Matching hot and Cold Cache objects are removed; cold file deletion is queued. |
|
|
| Query + real cache identity | IMPLEMENTED | Stored target and primary cache key are both available to invalidation. |
|
|
| `Vary` variants | IMPLEMENTED | Matching one representation removes the whole primary-key variant family. |
|
|
| Pre-PURGE fill race | IMPLEMENTED | Selective PURGE advances the publication generation, so any fill started before the operation cannot publish afterward; matching single-flight waiters are also released. |
|
|
|
|
### BAN
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| Rule without immediate full scan | IMPLEMENTED | BAN creation only records a rule. |
|
|
| Lookup enforcement | IMPLEMENTED | Hot/cold lookup rejects objects whose creation predates a matching active BAN. |
|
|
| GC | IMPLEMENTED | Lifecycle maintenance removes banned objects incrementally with a bounded batch. |
|
|
| Remove one rule | IMPLEMENTED | Authenticated `DELETE /api/cache/bans/{id}` and Cache-panel action. |
|
|
| Rule count/TTL bound | IMPLEMENTED | Maximum 1024 active rules; TTL is bounded to 1..604800 seconds. |
|
|
| New objects after BAN | IMPLEMENTED | BAN intentionally targets representations that existed before the rule; a fresh post-BAN fill may be stored. |
|
|
|
|
### API, panel and observability
|
|
|
|
| Requirement | Status | Implementation |
|
|
|---|---|---|
|
|
| Dedicated admin endpoint | IMPLEMENTED | `POST /api/cache/invalidate`. |
|
|
| PURGE/BAN type | IMPLEMENTED | `operation: purge|ban`. |
|
|
| exact/prefix/tag/regex/cache_key | IMPLEMENTED | Typed selector in API/OpenAPI and UI. |
|
|
| Vhost selector | IMPLEMENTED | Optional validated `vhost`; optional host filter is separate. |
|
|
| Explicit broad warning | IMPLEMENTED | Regex and prefix `/` require `confirm_wide=true`; UI shows a danger confirmation. |
|
|
| Result data | IMPLEMENTED | Operation, selector, scope inputs, affected count, optional BAN id, elapsed milliseconds and status. |
|
|
| Audit log | IMPLEMENTED | Operator and requested operation/scope/value are written through the existing administrative audit store. |
|
|
| Metrics | IMPLEMENTED | PURGE counts/entries, BAN create/remove/matches/active count plus collapsing/proactive metrics. |
|
|
| `Cache -> Purge / Ban` | IMPLEMENTED | Dedicated controls and active-BAN table in the Cache panel. |
|
|
| Per-object `Purge URL` | IMPLEMENTED | Cache object table exposes a targeted purge action. |
|
|
|
|
## Release gate
|
|
|
|
The 0.22.0 source scope is implemented and covered by Rust-independent package checks plus source-level Rust regression definitions. The following gate remains mandatory before treating the build as runtime-accepted:
|
|
|
|
```bash
|
|
bash dev.sh doctor
|
|
bash dev.sh check
|
|
bash dev.sh test
|
|
```
|
|
|
|
That gate must run on a host with the Rust toolchain and must be followed by the project's live H1/H2/H3/cache/compression/restart acceptance checks.
|