Repository navigation
fix(sglang): handle health signals from the tokenizer socket - #2879
Conversation
SGLang sends HealthCheckOutput directly to the tokenizer socket while the scheduler is busy. Refresh liveness for every signal and only dispatch signals with a request id, so request-less busy-path signals do not produce spurious unknown-request warnings. Signed-off-by: minghe-zty <116366231+minghe-zty@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe tokenizer loop now refreshes liveness when it receives a health signal and calls the health-check handler only when the signal has a truthy request ID. Tests cover missing, empty, and truthy request IDs. ChangesTokenizer health signal handling
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to The change lets busy-path health signals refresh liveness, so the health check no longer waits for its timeout. No merge-blocking risk was found in the supplied changes. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to This is a narrow health-check behavior change, with no identified expansion of access or privileges. Production signal freshness and duplicate-delivery behavior remain unverified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Description
Problem
SGLang 0.5.21 can send a
HealthCheckOutputdirectly to the tokenizer socketwhile the scheduler is busy. The dedicated tokenizer loop currently only
dispatches communicator responses, so it treats that health signal as unknown
and does not refresh
last_receive_tstamp. The custom gRPC HealthCheck RPC cantherefore wait until its 20-second timeout even though the scheduler responded.
The busy-path signal is constructed with
http_worker_ipconly, so itsinherited
ridcan beNone:https://github.com/sgl-project/sglang/blob/v0.5.21/python/sglang/srt/managers/scheduler.py#L4533-L4542
Solution
Recognize
HealthCheckOutputon the dedicated tokenizer socket beforecommunicator dispatch. Every such signal refreshes scheduler liveness, but only
a signal with a non-empty request ID is forwarded to
_handle_health_check_output(). This avoids a spuriousunknown request: Nonewarning for SGLang's request-less busy-path signal while preserving completion
for request-backed health outputs.
Changes
HealthCheckOutputmessageslast_receive_tstampfor both request-backed and request-less healthsignals
ridis missing or emptyrid=None, an emptyrid, and anormal health-check request ID
Test Plan
health output as an unknown type
python -m pytest tests/test_sglang_tokenizer_health.py tests/test_health_probe_logging.py -q-- 11 passed
python -m ruff check ...-- passedpython -m ruff format --check ...-- passedpython -m codespell_lib ...-- passedpython -m py_compile ...-- passedgit diff --check-- passedRust-wide cargo checks were not run locally because this environment has no
Rust toolchain. The change is confined to the Python SGLang gRPC servicer and
its engine-free tests.
Checklist
cargo +nightly fmtpassescargo clippy --all-targets --all-features -- -D warningspasses