sync: 鍚屾灞€鍩熺綉鏈€鏂颁唬鐮?(source master @ b69568e4)

This commit is contained in:
gozeros committed 2026-10-21 14:51:31 +08:00
1 parent 4f7f07504a
commit 8bc8b0e082
1651 files changed
+278599 -11416

No files matched your search

@@ -143,6 +143,12 @@ sequenceDiagram
**`StreamBridge` 的存在价值**:当生产者(`run_agent` 任务)和消费者(HTTP 连接)在不同的 asyncio task 里运行时,需要一个可以跨 task 传递事件的中介。Queue 同时还承担断连重连的 buffer 和多订阅者的 fan-out。
### Gateway 多进程约束
当前 `MemoryStreamBridge` 和 `RunManager` 都只保存当前 Python 进程内的实时状态。首次 `POST /runs/stream` 会在同一个 uvicorn worker 中创建后台 run 并消费事件,因此首连可以正常工作;但响应里的 `Location`、显式 `/join` 和携带 `Last-Event-ID` 的恢复请求都是新的 HTTP 请求。多个 uvicorn worker 会独立调度这些请求,恢复请求一旦落到另一个 worker,该进程看不到原 worker 的 live run 和事件缓冲,只能把持久化 run 记录当作没有可恢复流并提前返回 `end`。持久化 checkpointer/RunStore 不能替代实时事件桥。
因此,使用内存 bridge 时 Gateway 必须运行 **1 个 worker**。两个生产离线启动脚本 `scripts/start_backend-online.sh` 与 `offline-backend-20260512/start_backend.sh` 都默认并校验 `GATEWAY_WORKERS=1`;显式配置更大值会拒绝启动,除非同时设置 `DEERFLOW_ALLOW_UNSAFE_MULTIWORKER=1` 确认接受丢失重连流的风险。真正支持多 worker 需要共享的 StreamBridge 与 live-run 控制面(发布、订阅、结束、取消和活跃 run 查询),不能只依赖负载均衡粘性或数据库中的最终状态。
---
## DeerFlowClient 路径:sync + in-process