Files
Cyrene_v2/internal
AskaEth 48a5bb89f2 fix(config): owner_lane.json 并发落盘不再损坏/丢更新(review p1)
review p1:Set 的固定 tmp 名(path+".tmp")+ 落盘发生在 mu.Unlock() 之后 ⇒
并发 Set 撞同一临时文件把 JSON 写坏(load 退回默认「甲」、主人刚说的「少说点」
白说且无提示),或 rename 完成顺序与新快照先后不一致而丢更新。

修法(两条都取,各司其职):
- 落盘挪进锁内(Set 全程持 s.mu):并发 Set 完全串行 ⇒ 快照与 rename 顺序一致,
  不可能丢更新。落盘是一个小 JSON,持锁 I/O 代价可忽略;读侧读内存、不读文件。
- 每次用 os.CreateTemp 新建临时文件(仓库同款先例 internal/user/save.go),
  不再撞固定 tmp 名;CreateTemp 以 0600 打开并再 chmod 一次,任一步失败都清掉 tmp。
- 旧 save(快照) 换成 saveLocked()(调用方须持锁,直接 marshal s.cfg)。

测试:新增并发用例 TestOwnerLaneStoreConcurrentSetKeepsAllUpdates(24 轮 × 24 写者),
断言 ① 文件始终是合法 JSON、② 每一次成功的 Set 都能在最终文件读到(不丢更新)。
修前红(原实现在同一用例上):5/5 轮复现,两种失败模式都抓到 ——
"并发落盘把配置写坏了(文件不是合法 JSON):invalid character '\"' after top-level value"
与 "丢更新 —— 键 qq-obv11|g-N-M 不在最终文件里";修后连续 3 次绿,-race 下亦 ok。
Bridge.SetOwnerLanePolicy 无需改动:它在 ownerLaneMu 下设内存后调注入的 store,
串行化由 store 侧保证。
2026-10-13 21:07:46 +08:00
..