Repository navigation
Replies: 1 comment
|
writeFile(temp) -> rename(temp, target) 后未 fsync 就报成功——原子替换的"持久性谎言"(rename 原子但不持久,断电丢数据)。 插件做持久化写入时建议:rename 后 fsync 目录。这类工程细节第 4 章插件开发有提及:https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/04-plugin-dev.md |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
@deepseek-ai/dsh-atomic-writereports a successful replacement afterwriteFile(temp) -> rename(temp, target)without syncing either the staged inode or the target directory. On POSIX, atomic visibility and crash durability are separate guarantees: readers cannot observe a partial file, but a power loss after the promise resolves can still lose the new bytes or unwind the renamed directory entry.This primitive backs the file settings provider, the local credential store, and Agent Preset authoring, so the gap affects user-owned persistent state rather than a temporary cache.
Reproduction
The regression test observes
FileHandle.sync()while writing a nested document. Againstmaster, the write resolves successfully and the observed sync list is empty:A second fault-injection test makes the staged file's
sync()fail. The required behavior is to reject, retain the old target, remove the temp sibling, and release the settings writer lock.Root cause
The helper used the promise-level
writeFile()convenience API and immediately renamed the completed temp path. It never held a file handle from which it could callsync(), and it did not open/sync directory handles before or after publication. Recursive parent creation therefore had the same durability gap as the final rename.Impact
After a settings, credential, or preset write reports success, an abrupt host crash or power loss may restore the old file or remove a newly created file/directory. Callers have no indication that the acknowledged update was not yet durable.
Proposed fix
The patch makes the POSIX success boundary explicit:
If content sync fails, the old target remains untouched and staging is removed. A final directory-sync failure is reported even if the complete new target is already visible, because durability has not been proven.
Windows still syncs staged file bytes before rename. The documentation deliberately retains a Windows limitation: Node does not expose directory
fsyncor a write-through replacement primitive, so this patch does not claim POSIX-equivalent namespace durability there.Patch
The branch is isolated to this change and includes matching English/Chinese documentation plus the translation sidecar.
Verification
git diff --checkpassed.All reactions