ProxyState.config_apply_age defaults fail-open — make the production constructor fail-closed
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 157
- Forks
- 32
- Avg merge
- 1h 25m
- Merged PRs (30d)
- 145
Description
Context
ProxyState.config_apply_age (crates/aisix-proxy/src/state.rs) is the probe behind GET /readyz's config-freshness gate. Every constructor defaults it to None, and the handler treats a None field as "config ok unconditionally" (readiness gates on shutdown only):
let config_block = state
.config_apply_age
.as_ref()
.and_then(|probe| crate::health::config_readiness_block(probe()));
Production relies on aisix-server wiring with_config_apply_age in every mode (etcd/managed → supervisor.watch_status(); file → always-fresh). If a refactor ever drops that wiring — e.g. while reworking the adjacent admin-listener bootstrap during the Admin API removal — /readyz silently downgrades to shutdown-only readiness and every test stays green, because the field-None output is byte-identical to wired-and-fresh ([+]config ok). That would re-open the class of #591: an orchestrator routing traffic to a not-yet-configured or stale-watch instance.
A router-level unit test now pins the plumbing (a wired probe returning None → 503), but it cannot pin the wiring itself.
Proposed fix
Make the production constructor fail-closed: default the probe to || None ("no freshness signal = not ready") in ProxyState::new/with_components, and have tests that don't care about readiness opt out explicitly (e.g. .with_config_always_fresh()). Then a dropped wiring makes /readyz 503 permanently — caught loudly by the harness readiness gate and every e2e — instead of passing silently.
Surfaced by the independent audit of #802.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in crates/aisix-proxy/src/state.rs at ProxyState::new and with_components, then trace the GET /readyz handler and aisix-server's with_config_apply_age wiring for each mode. Review the router-level readiness test and harness/e2e readiness checks. Done means an unwired production probe fails readiness, while tests that do not exercise freshness opt out explicitly and the existing readiness checks pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100