fix(pylon): probe /v1/health/ready when the upstream serves no /health - #907
Conversation
Pylon gated startup on a hardcoded GET /health against the local inference server and exited when it did not answer, so an OpenAI-style engine that serves only /v1/health/ready never completed bringup and crash-looped on a healthy inference container. Probe an ordered candidate list instead, defaulting to /health then /v1/health/ready, remember the path that answers, and forward Stargate's /health RTT probe to that same path so the routing signal follows. Startup now retries the probe for --upstream-health-wait-ms (default 60s) before failing, which also removes the restarts that happen while the engine is still loading. New flags: repeatable --upstream-health-path and --upstream-health-wait-ms. Signed-off-by: Max Xing <mxing@nvidia.com>
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (16)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
🛡️ CodeQL Analysis🚨 Found 2 issue(s) Severity Breakdown:
📋 Top Issues🔗 View full details in Security tab 🕐 Last updated: 2026-08-17 15:28:43 UTC | Commit: b560a2e |
|
Shouldn't we be passing down that health endpoint value that we set in the NVCF API? |
The llm-worker container already receives INFERENCE_HEALTH_ENDPOINT, sourced from the function's health URI, but pylon is configured by CLI args only, so the value went unused and pylon guessed the path instead. Pass it through as --upstream-health-path when the function keeps the health check on HTTP and on the inference port, which is what pylon actually probes. Configured paths now sit ahead of pylon's built-in candidates rather than replacing them, so a health URI that does not answer still falls back instead of stranding a healthy upstream. Signed-off-by: Max Xing <mxing@nvidia.com>
newLLMRouterClientContainer now forwards INFERENCE_HEALTH_ENDPOINT as --upstream-health-path, so pylon probes the endpoint the function declares instead of guessing. It is skipped when the health check is gRPC or on a port other than the inference port, since pylon probes over HTTP against the inference port. Configured paths are also tried ahead of pylon's built-in /health and /v1/health/ready rather than replacing them, so a health URI that does not answer still falls back instead of stranding a healthy upstream. |
|
🎉 This PR is included in version stargate-v0.9.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
TL;DR
Pylon gated startup on a hardcoded
GET <upstream>/healthand exited when it did not answer, so engines that serve only/v1/health/readycrash-looped next to a healthy inference container. Pylon now probes an ordered candidate list, andicms-translatepasses down the health endpoint the function already declares.Additional Details
Pylon side:
UpstreamHealthPaths(newcrates/pylon-lib/src/upstream_health.rs) holds the candidate list and the resolved index. Configured paths are probed first, followed by the built-in/healthand/v1/health/ready, so a path that does not answer falls back instead of stranding a healthy upstream.check_upstream_healthprobes the resolved path first, falls back to the rest, and records the winner./healthRTT probe is rewritten to the resolved upstream path inside pylon. The tunnel wire path stays/health, so mixed router/pylon versions need no lockstep rollout.--upstream-health-wait-ms(default 60s) before failing, which also removes the restarts seen while an engine is still loading.0keeps the old probe-once behavior.--upstream-health-pathand--upstream-health-wait-ms. Both default to working behavior.Translate side:
llm-workercontainer already receivesINFERENCE_HEALTH_ENDPOINTfrom the function's health URI, but pylon takes CLI args only, so the value was never used.newLLMRouterClientContainernow forwards it as--upstream-health-path.icms-translategoldens and synced the vendored copy undersrc/compute-plane-services/nvca/vendor.Rollout order
--upstream-health-pathis a new flag, and pylon rejects unknown arguments, so the pylon image must roll out with or before the translate change. A worker still pinned to an older pylon exits at startup withunexpected argument '--upstream-health-path' found. OnlyfunctionType: LLMworkloads run this container.For the Reviewer
crates/pylon-lib/src/quic_http_tunnel/core.rsis the part worth close reading: the health rewrite happens beforesend_upstream_request, so only requests matched byis_health_request_pathare affected.For QA
cargo test --workspace,cargo fmt --check,cargo clippy --workspace --all-targets -- -D warnings, andgo test ./pkg/icms-translate/...pass. Two pre-existing local failures reproduce unchanged onmainin the same environment and are unrelated to this change:stargate::tests::occupied_metrics_port_fails_before_runtime_construction, andcmd/icms-translate TestRun, which compares generator output against goldens that carry an SPDX header the generator does not emit (39 subtests before and after).New tests cover the fallback probe, resolved-path reuse, the no-candidate case, configured-path precedence, fallback when a configured path is wrong, the tunnel probe rewrite with and without a query string, the startup wait, the flag-to-config wiring, and the four translate cases (declared endpoint, divergent health port, gRPC protocol, absent endpoint).
QA needed: deploy an LLM function on an engine image that serves only
/v1/health/readyand confirm the worker pod reaches full readiness.Issues
Closes #906
Checklist
Summary by CodeRabbit
New Features
/healthand/v1/health/readyfallbacks.Documentation