fix: 终局节点 nodeOf 先于结算构建(nodeOf 失败则未结算,防已结算却报错)
This commit is contained in:
@@ -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**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user