一句话
这是 #380 的反方向:容器里 read_write 挂载的本地改动,推回 memory store。14 条小取舍,建议全部选 A(照现在实现)。预发冒烟脚本写了还没跑;本地测试已过。
- 1写回经什么口进 store建议 A
- 2删除是否可配置建议 A
- 3删会话前最后一次写回失败怎么办建议 A
- 4删会话时 pull 不是 complete建议 A
- 5空闲关停前写回失败建议 A
- 6空闲关停多占时间建议 A
- 7标记文件缺失或被改建议 A
- 8归档的 store建议 A
- 9时机文字冲突怎么解建议 A
- 10删会话等串行队列多久建议 A
- 11最终同步里第一次看到的本地删除建议 A
- 12超时但其实已落库的写建议 A
- 13冲突撞上超预算文件建议 A
- 14memory 版本的 session_id 取哪建议 A
回「全同意」就按建议;有不同意的,回编号 + 意见就行。
背景
#380 已合:store → 容器(下行)。#381 做反方向:容器 → store(上行写回)。跟下行同一拍触发(回合开头,或命令边界离上次超过 15 秒);read_only 从不写回。
这次做的方向(上行写回)
容器本地(改过)
notes.md 改了todo.md 新建→
memory store(真源)
notes.mdtodo.md冲突时 store 赢;删文件要「下一次同步」才确认;单条超 102400 字节 / 非 UTF-8 / 超总量就跳过并记一行。
1 下行先对齐
2 找改动
3 写前回检
4 冲突 store 赢
最终同步:空闲关停 / 删会话前
云端 agent 已写完并开草稿 PR。下面建议都是「照现在做」。回「全同意」就按建议。
1写回经什么口进 store
走 MemoryStoreDO 新 RPC
A · 建议MemoryStoreDO 新增两条按 path 的 RPC(writeMountFile / removeMountFile),复用已有的 precondition 和按 sha256 删除;不改表。代价:多两条内部 RPC,对外 API 不变。
B走公开 /v1/.../memories:要先按 path 找 id、多一跳 Worker 鉴权,Computer 还要持有 API 密钥。代价:Computer 持密钥风险更大,路径也更绕。
为啥选 A:内部挂载本来就该走 DO 直连,别给 Computer 塞 API 密钥。
建议选 A
2删除是否可配置
照 CMA 默认,不可配置
A · 建议不可配置,照 CMA 默认 enabled:下一次同步确认本地还没回来,才删 store。代价:想关掉「自动删」暂时没开关。
B做成开关:要加字段和路由,还要对齐 CMA 的 disabled 语义。代价:接口和测试都膨胀,本轮收益不大。
为啥选 A:先对齐 CMA 默认行为;真要开关可以后开。
建议选 A
3删会话前最后一次写回失败怎么办
打日志,照常删
A · 建议console.warn 列出路径,删会话照常继续,改动随会话丢掉。代价:极端情况下最后几笔改动可能丢。
B抛错让 SessionDO 每 30 秒重试;或有限次重试。代价:store 不可达时清理一直拖着;或多一套计数。
为啥选 A:删会话优先收敛;丢掉比卡死清理更可控。
建议选 A
4删会话时 pull 不是 complete
整段不写回
A · 建议整段不写回,只打日志。代价:容器里已改、还没拉回 DO 的内容会丢。
B只写 VFS 里已有的。代价:可能把容器里更新过、还没拉回的文件的旧版本写进 store。
为啥选 A:宁可少写,也不要用过期本地拷贝污染 store。
建议选 A
5空闲关停前写回失败
改动留着,下次再送
A · 建议改动留在 DO 的 VFS,下次同步再送;容器照常 destroy。代价:短暂不可达时,要等下一次同步。
B不 destroy、等下一拍。代价:store 长时间不可达时容器和租约一直占着。
为啥选 A:别为了写回把租约和容器挂死。
建议选 A
6空闲关停多占时间
关停里做最终同步,最多约 30 秒
A · 建议最终同步在关停这条串行任务里,后面排的命令最多多等 30 秒。代价:关停瞬间略慢。
B关停不做最终同步。代价:空闲之后的最后几条改动要等下一个回合;会话就此结束则丢失。
为啥选 A:多等几十秒,换最后几笔写回更稳。
建议选 A
7标记文件缺失或被改
该目录不写回
A · 建议该目录不写回,记一行。回合开头的还原会补回标记;之后被删的文件走删除确认,可能把 store 删空。代价:用户乱改标记文件时,可能误删 store 内容。
B从 store 重新下载整个目录。代价:本地改动全丢。
为啥选 A:保住本地改动优先;标记文件本就不该人手改。
建议选 A
8归档的 store
不写,每拍再问一次
A · 建议不写,改动留着,记一行;有改动的每一拍都问一次 WorkspaceDO。代价:多一次 RPC。
B第一次看到归档就记住不再问。代价:以后若能取消归档就不再写回。
为啥选 A:少一点状态机,取消归档后还能自动恢复写回。
建议选 A
9时机文字冲突怎么解
按规则:空闲关停前 + 删会话前
A · 建议旧文字写「回合结束和空闲关停」,规则写「空闲关停前 + 删会话前」。按规则做,回合结束不单独做。代价:文档旧表述要改清楚。
B回合结束也做一次。代价:每个回合多一次 RPC;下个回合开头本来就会做。
为啥选 A:跟下行同步同一拍就够,别每个回合多打一轮。
建议选 A
10删会话等串行队列多久
至多 60 秒
A · 建议至多 60 秒(2×30 秒),之后开始的任务不写。代价:排队很久时可能跳过最终写回。
B不设上限。代价:一条卡住的容器命令能把 DELETE 拖到 120 秒以上。
为啥选 A:删会话要有截止,不能被一条慢命令拖死。
建议选 A
11最终同步里第一次看到的本地删除
只记下,不删 store
A · 建议只记下,不删 store;删会话时随会话丢掉。代价:删会话场景下,确认不了的删除不会进 store。
B最终同步直接删。代价:偏离 CMA「下一次同步确认」。
为啥选 A:严格跟 CMA:删要「下一次同步」确认。
建议选 A
12超时但其实已落库的写
下次下行静默对齐
A · 建议下一次下行发现 store 的 sha256 等于本地,静默收下,不记冲突。代价:中间有一小段「以为没写成」。
B带幂等键。代价:要改 MemoryStoreDO 的表。
为啥选 A:零迁移就能自愈,别为了这个加表。
建议选 A
13冲突撞上超预算文件
store 赢,照样写进本地
A · 建议store 赢,即使 store 那份让总量超过 2000 条 / 32 MiB 也写进本地。代价:本地短暂可能超预算。
B冲突时再查预算,超了就删本地。代价:用户和 store 的版本都看不到。
为啥选 A:冲突时优先让人看到 store 真源,别两边都空。
建议选 A
14memory 版本的 session_id 取哪
取 ComputerDO 的名字
A · 建议取 ComputerDO 的名字(idFromName(session_id))。代价:依赖命名约定。
BSessionDO 每次传进来。代价:每个 Computer RPC 多一个参数。
为啥选 A:命名本来就绑 session,少传参数更干净。
建议选 A
怎么回
微信直接回就行:
- 全按建议 → 回「全同意」
- 有几条要改 → 回「3 选 B」或「3 要重试删会话写回」这种
编号 1–14 专指本页 PR #381,别跟 #380 的 1–7 混。页里勾选只存本机,拍板以微信为准。