执行摘要
本PR修复了启用指标时非流式请求中止失效的bug,通过引入纯ASGI中间件适配器替代Starlette的BaseHTTPMiddleware,恢复request.is_disconnected()功能,确保客户端断开时请求能正确中止。新增单元测试验证修复,不影响现有指标收集。
功能与动机
当启用--enable-metrics时,非流式请求在客户端断开(如curl被Ctrl+C取消)后不会中止,导致服务器资源浪费。Issue #20623详细描述了此问题:根因是@app.middleware("http")使用的BaseHTTPMiddleware替换了ASGI receive callable,破坏了request.is_disconnected()。修复后能恢复中止功能,提升系统资源管理。
实现拆解
- 修补中间件:在
python/sglang/srt/utils/common.py中添加patch_app_http_middleware(app)调用,在指标中间件应用前修补。
- 纯ASGI适配器:新增
python/sglang/srt/utils/http_middleware_patch.py,定义_PureASGIDispatch类,其__call__方法传递receive不变,保持request.is_disconnected()工作。
python
async def __call__(self, scope, receive, send):
if scope["type"] != "http":
await self.app(scope, receive, send)
return
request = Request(scope, receive)
...
- 单元测试:新增
test/registered/scheduler/test_abort_with_metrics.py,使用mock模拟ASGI环境,直接测试is_disconnected()行为。
评论区精华
- gemini-code-assist[bot]:建议将import移动到文件顶部,遵循PEP 8风格规范。
"To adhere to PEP 8 guidelines and improve code clarity, this import should be moved to the top of the file with other imports."
- hnyls2002:建议改进测试策略,从集成测试改为单元测试,提高效率。
"The test in test_abort_with_metrics.py launches a full server with model loading (est ~180s)... This can be tested much faster and more precisely with unittest.mock."
最终测试被重写采纳此建议。
风险与影响
- 技术风险:中间件替换可能干扰其他中间件;依赖Starlette内部机制,未来更新可能失效;测试覆盖主要针对中间件层,需确保端到端场景被现有测试覆盖。
- 影响分析:用户端bug修复,避免资源浪费;系统恢复中止功能,改善内存管理;团队引入补丁增加维护负担,但提供了针对Starlette已知问题的解决方案。
关联脉络
本PR直接关联Issue #20623,是该issue的具体实现修复。未提供历史PR信息,但从讨论看,测试策略优化体现了团队对测试效率的重视,可能影响后续测试设计。
参与讨论