Files
SimpleFarm/.workbuddy/memory/2026-09-23.md
T
snowy-yang d1692d7b10 docs: 记忆与验收技能跟上——存档改动必须真机验自动落盘
单元测试抓不住 autosave 失效(dirty 被高频清零这件事测试里复现
不了真机时序),所以技能里加一条:动了存档/会话层,必须 0 客户端
在线做一个动作、等 60s、直接查库那一行有没有更新。
2026-09-23 20:54:13 +08:00

31 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 2026-09-23 修网页版「点播种没反应」+ 顺手挖出自动存档失效的真 bug
- 用户报网页版点播种没反应。服务端 plant 动作完全正常 → 定位到前端。
- **根因 1(前端)**:播种按钮走 `window.prompt` 选作物,重置走 `window.confirm`
——这俩在 sandbox iframe(内置预览面板)里会被**静默屏蔽**:不弹窗、直接返回
null,于是"点了没反应"。普通浏览器里是好的,所以一直没暴露。
修复:改成页面内弹层(`#pickmask` + `openCropPick`,未锁定作物生成按钮 +
取消按钮,点遮罩关闭);重置改两步确认(第一次点变"再点一次确认",3 秒还原)。
- **根因 2(后端,真 bug)**:顺着验证存档时发现 `default` 牧场**根本没写进库**
——内存里每次重启都是新档。排查出 `session.dirty` 一个标志位伺二主:
Publisher 推送循环每 ~250ms 就把 dirty 清掉(无人在线时更是直接清),
而 `autosave()` 每 60s 才看一眼 dirty——窗口太小,**自动存档几乎永远不触发**
(约 0.4% 撞率)。进度只在手动存档/优雅停机时落盘,进程被强杀就全丢。
修复:新增 `session.unsaved` 专管「有变化没落盘」,`_on_change`/`load`/
`touch`/`advance_day` 置位、只有成功的 `save()` 清位;`autosave()` 改看
unsaved;dirty 继续只管推送节流。hub.py 的推送循环一字未动。
- 两只旧测试(`test_autosave_skips_when_clean` / `..._writes_when_dirty` /
`autosave_all...`)直接操纵 dirty 驱动 autosave,固化了被修掉的耦合——
全部改成用 unsaved 表达意图。新增回归测试:
「推送循环清了 dirty 也要照常落盘」「没有新变化不重复写库」。
- **真机验证**:0 客户端在线、纯 HTTP 种一块地,70 秒内看到库行更新
(gold 120→112,种子钱都对得上)。
- 门禁:ruff/pyright 全绿,515 项测试 OK(skip 35)。
### 教训
- 嵌入预览面板里 `window.prompt`/`confirm`/`alert` 都不可信,交互一律用页面内
弹层实现。
- 一个布尔标志被两个子系统共用时,其中一个高频清零,另一个低频读取——
低频的那个等于瞎了。存盘依据必须由"成功的写入"来清。