fix: 终局节点 nodeOf 先于结算构建(nodeOf 失败则未结算,防已结算却报错)

This commit is contained in:
2026-08-13 17:04:01 +08:00
parent aea79d8c5a
commit 83fbf61e8a
2 changed files with 20 additions and 8 deletions
+5 -5
View File
@@ -156,6 +156,11 @@ func (s *levelPlay) Choose(ctx context.Context, parentUid, childId, levelId, nod
return node, nil, nil
}
// v2.1:终局节点剧本先于结算构建(只读查询失败则未结算,无副作用)
finalNode, err := nodeOf(ctx, levelRec, nextRec)
if err != nil {
return nil, nil, err
}
// 终局:路径流水在锁内结算后记录,避免状态读到本次到达导致重复结算误判
settle, err := common.WithLock(ctx, fmt.Sprintf("child:%d:level:%d", childId, levelId), 10*time.Second, 3, 200*time.Millisecond, func() (*FinalSettle, error) {
return s.settle(ctx, child, levelRec, nextRec, nodeId, optionId)
@@ -163,11 +168,6 @@ func (s *levelPlay) Choose(ctx context.Context, parentUid, childId, levelId, nod
if err != nil {
return nil, nil, err
}
// v2.1:终局节点剧本随结算返回(前端先演绎结局台词再跳结算页)
finalNode, err := nodeOf(ctx, levelRec, nextRec)
if err != nil {
return nil, nil, err
}
settle.FinalNode = finalNode
return nil, settle, nil
}
@@ -1146,18 +1146,30 @@ git commit -m "docs: 剧情演绎文档补充 + 全量剧本生成导入"
- [ ] **Step 2: Choose 终局分支返回终局 Node**
`biz/service/level_play.go` Choose 中 `WithLock` 调用之后、`return nil, settle, nil` 之前插入
`biz/service/level_play.go` Choose 终局分支改为**先 nodeOf 再结算**(内容表只读查询失败则未结算,无副作用;与决策分支同顺序)
```go
// v2.1:终局节点剧本随结算返回(前端先演绎结局台词再跳结算页
// v2.1:终局节点剧本先于结算构建(只读查询失败则未结算,无副作用
finalNode, err := nodeOf(ctx, levelRec, nextRec)
if err != nil {
return nil, nil, err
}
// 终局:路径流水在锁内结算后记录,避免状态读到本次到达导致重复结算误判
settle, err := common.WithLock(ctx, fmt.Sprintf("child:%d:level:%d", childId, levelId), 10*time.Second, 3, 200*time.Millisecond, func() (*FinalSettle, error) {
return s.settle(ctx, child, levelRec, nextRec, nodeId, optionId)
})
if err != nil {
return nil, nil, err
}
settle.FinalNode = finalNode
return nil, settle, nil
```
`nodeOf` 与决策分支同函数、同签名,构建选项 + 元素 + buildNode;只读查询,锁外执行安全。)
`nodeOf` 与决策分支同函数、同签名,构建选项 + 元素 + buildNode;只读查询,锁外执行安全。审查补充:nodeOf 与结算无数据依赖,先构建可避免「已结算但返回 err」的异常路径。
> 审查记录(aea79d8 双审查 APPROVE):
> - SHOULD-FIX(已修):原实现「锁内结算 → 锁外 nodeOf」,nodeOf 失败时已结算却返回 err(logRoute 多写一条终局流水 → FailStreak 误算)。改为 nodeOf 先于 WithLock,失败则未结算。
> - NIT(不修):终局节点无选项,nodeOf 内 NodeOption 查询返回空集,成本极低;FinalNode 透出链路无新增单测,Step 5 既有测试通过即可
- [ ] **Step 3: dto FinalSettle 加 FinalNode**