feat(gateway,loop): 忙时并行回合基础管线(I1′ 有条件放宽)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- turnId 由编排器生成、loop Run 复用(硬前提:否则 turn_begin 与流帧各铸一个,客户端两级分桶立即失配)
- StateSink 增带 turnId 的变体(未接线时退化为现签名,不丢状态帧)
- 上行 chat.parallel(WS chat 帧 + REST 三入口同形;省略 = 逐字不变)
- 单会话额度默认 2 / 硬上限 3 / <2 关闭;额度满或未声明 ⇒ 落回既有排队语义
- I1′:checkpoint 归属、历史配对、忙态计数三处从会话级单例升为路级
- session_idle 收紧为「所有在途路收尾且 pending 空」(仅并行时生效;单路逐字不变)
- 预留接口(形状定死、无实现无接线):tool/legfile.go 的 FileClaimer / ErrFileBusy / WithLegID
- 顺手修一个真 bug:并行路 ctx 派生自提交请求作用域,REST 同步入口一写响应就把它连坐杀死(改 context.WithoutCancel 派生)
- 23 个新用例(含 -race -count=3);变异 6 条(turnId 复用 / idle 时点 / 并行升级 / checkpoint 键 / 编排器交 id / pending_ack reason)
- 契约变更点 10 条待监工升 v0.65(本人未改 Docs/**)
This commit is contained in:
AskaEth committed 2026-10-05 09:18:50 +08:00
1 parent 7d2ff74cfc
commit 89e13cf53d
23 files changed
+1921 -275

No files matched your search

@@ -7,8 +7,10 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
)
// 本文件把「同一会话最多一个在途回合」从一句约定变成可等待的进程内围栏
// (design/15 §3 与裁决 13.4.5 的组合要求)。
// 本文件把「同一会话的**串行续跑链**上一次只有一个回合」从一句约定变成可等待的
// 进程内围栏(design/15 §3 与裁决 13.4.5 的组合要求;design/15 §2.5 落地真并行后,
// 需要这条护栏的仍只是串行链 —— 显式声明的并行路用**自己的 checkpoint 归属键**
// 消除同一竞态,因此不接入这条链)。
//
// 中断必须**立即**把会话交回空闲并接受新消息(design/15 §3),但被取消的
// 回合仍在收尾:loop 直到它自己的 Run 返回之前,才把被放弃回合的快照落定
@@ -21,9 +23,9 @@ import (
// 围栏关掉这条竞态窗口,且不阻塞调用方:新消息照样被立即接受、Submit 立即
// 返回(非阻塞是硬约束),只是它的回合要等上一回合真正返回之后才开始。
// turnFence 是一次回合的启动围栏。wait 是上一回合的收尾信号(nil 表示没有
// 在途的上一回合,无需等待);done 是本回合的收尾信号,在本回合返回时关闭,
// 从而放行等它的下一回合。
// turnFence 是**一条路**的启动围栏。wait 是上一串行回合的收尾信号(nil 表示没有
// 在途的上一回合,无需等待 —— 并行路与续跑路都用 nil);done 是本路的收尾信号,
// 在本路返回时关闭,从而放行等它的下一路。
type turnFence struct {
wait <-chan struct{}
done chan struct{}