bug: A config reload stops the old pipeline while requests are still using it
维护者通常 1 天内回复
评估
调研方向
Start with core/reloader/reloader.go and the drain goroutine, then trace how Holder.Run pins a pipeline and how requests reach RunFinish; also find how WebSocket turns hold pipelines. The issue proposes stopping old pipelines when their holders finish, with a maximum wait and logging for remaining requests. Done means requests can finish on a live pipeline after reload, while the ceiling still ensures abandoned pipelines are eventually stopped.
由索引模型根据 Issue 内容生成。
描述
Problem
A config reload stops the old pipelines on a fixed timer: 30 seconds after the swap, whether or not anything is still using them (core/reloader/reloader.go, the drain goroutine after pipelines swapped). Stop calls each plugin's Shutdown.
Since #1561, a request keeps the pipeline it started on: Holder.Run pins it on the request context, and every later phase (RunResponse, RunResponseFrame, RunFinish, Resend) runs on that pin. That fixed the crash #1561 reported. But it means any request still open 30 seconds after a reload finishes on a pipeline whose plugins have shut down. Long requests are ordinary here:
- a long SSE inference stream;
- a CONNECT tunnel, whose Finishers run when it closes;
- a Codex Responses WebSocket turn (#1467), which keeps the pipeline it started on.
#1561 handled the one plugin where this skipped policy: cpex now follows fail_open when it is not ready. It did not change when the reloader stops a pipeline.
What happens today
Among plugins that tear something down in Shutdown, these are the ones a request reaches after Stop, read from the code (not reproduced):
lineage(OnFinish): the request's response span is dropped, since the tracer provider is shut down and the OTel SDK ignores spans that end after it.session-budget(last frame): the tokens reach the old instance's cache, and the Redis write fails with a WARN. The new instance never sees them.script(frames, last frame): the worker is shared with the new build when the script did not change. A changed script's old worker has stopped, so the hook fails, and underfail_closedthat is a late, recorded refusal.cpex: denies or allows perfail_open(#1561).
Nothing crashes, and nothing the client receives changes. The laptop's default pipeline (inference-parser, mcp-parser, a2a-parser, tool-prune) has none of these.
Possible approach
Stop an old pipeline when nothing holds it, not after a fixed delay:
- Count holders: increment when
Holder.Runpins the pipeline, and decrement after the request'sRunFinish. Paths that pin a pipeline outsideHolder.Run(the WebSocket turns) would hold it the same way. - The reloader waits for the count to reach zero, with a ceiling (minutes, not seconds), so a tunnel left open for hours cannot keep a pipeline's resources forever. Past the ceiling it stops the pipeline as it does today, and logs how many requests were still on it.
Raised in
CodeRabbit's review of #1467, about WebSocket turns. The same exposure exists on main for every long-lived request, so it is tracked here rather than fixed in that PR.
- 主要语言
- Go
- 星标
- 23
- 派生
- 44
- 平均合并
- 14 小时 38 分钟
- 30 天内合并 PR
- 254
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
rossoctl/cortex 的其他 Issue
-
feature: let `session.archive` set where it writes, so a second Cortex can keep its own sessions未关闭enhancement
难度 4/5 3-5 天 新手友好度 54/100
维护者通常 1 天内回复
-
feature: agentop observe — show a request and its response as one row可能已有人在做 @huang195 今天认领。 未关闭enhancement ux
rossoctl/cortex#1681 · 已指派 1 人 ·
维护者通常 1 天内回复
-
feature: agentop observe — search user prompts and agent responses across a session's events可能已有人在做 @huang195 今天认领。 未关闭enhancement ux
rossoctl/cortex#1680 · 已指派 1 人 ·
维护者通常 1 天内回复
-
feedback laptop
难度 5/5 一周以上 新手友好度 28/100
维护者通常 1 天内回复
-
chore: Remove the decline_responses_websockets translation after a deprecation release可能已有人在做 @Alan-Cha 于 4 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 55/100
rossoctl/cortex#1625 · 已指派 1 人 ·
维护者通常 1 天内回复
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 80/100
-
/shutdown/ready can fail to return an HTTP response when readiness takes longer than the server write timeout可能已有人在做 @floriankoch 今天认领。 未关闭triage
难度 2/5 1-3 小时 新手友好度 76/100
envoyproxy/gateway#10562 ·
维护者通常 1 天内回复
-
Adding an LDAP group reports every search failure as "LDAP Group DN is not found"可能已有人在做 @Daksha1611 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100