fix(fs): fs.write 改用每请求唯一临时文件,避免并发保存互相损坏 - #764
Open
nanami-0713 wants to merge 1 commit into
Open
nanami-0713 wants to merge 1 commit into
nanami-0713 wants to merge 1 commit into
Conversation
…ve corruption fs.write 的临时文件名只含 pid,同进程内对同一路径的并发保存共享同 一个 tmp:两个 writeFile 会交错/相互截断,先完成者 rename 走 tmp 后,另一个 rename 必然 ENOENT 报错,或目标文件最终是两份草稿的字 节混合,而编辑器仍显示"已保存"。"open to the side"会为同一路径 开第二个编辑器 tab,窗口期真实存在。 对齐 writeWorkspaceUpload 的既有方案(fs-operations.ts):隐藏文件 + randomUUID + .tmp 后缀,并给 writeFile 加 wx 标志。失败路径的 rm 也因名字唯一不再可能误删他人正在写的 tmp。 新增契约测试:同路径并发 fs.write 全部成功且文件内容必为其中一份 完整草稿。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
fs.write(src/index.ts)的临时文件名是${path}.dsh-sidebar-tmp-${process.pid}——同一进程内唯一,与请求无关。对同一路径的两次并发保存共享同一个 tmp:writeFile交错/相互截断,最终rename进目标的是两份草稿的字节混合,而两端编辑器都显示"已保存"rename必然 ENOENT 报错rm(tmp, {force:true})还可能删掉另一方正在写的 tmp触发窗口真实存在:"open to the side"会为同一路径铸造第二个编辑器 tab(
EditorHost.tsx),两个 tab 的保存只在各自组件实例内用savingRef串行化,同一进程内对同一路径的两次保存可以在 writeFile→rename 窗口内重叠。仓库里其实已有正确方案:
writeWorkspaceUpload(src/fs-operations.ts:70)用「隐藏文件 + randomUUID + .tmp」并注释了"The unique temp name keeps concurrent uploads to the same target independent"——fs.write没有得到同样处理。修复
对齐 upload 方案:
.${basename(path)}.dsh-sidebar-tmp-${randomUUID()}.tmp,另加wx标志(随机名碰撞时快速失败)。名字唯一后,失败路径的 rm 也不可能再误删他人正在写的 tmp。测试
新增契约测试:同一路径并发两次 fs.write,断言两次调用全部成功且最终文件内容必为其中一份完整草稿(非字节混合、无 rename 失败)。竞态命中本身依赖 OS 调度,测试作为契约守卫;核心论据是共享 tmp 名的代码事实。