导出注册表临时文件名加上时间戳

export/registry.rs:temp_path 在 pid 与序号之外再带纳秒时间戳,避免崩溃残骸被同 pid 新进程撞上导致 create_new 误失败。
This commit is contained in:
2026-10-06 21:07:27 +08:00
parent c02f499d24
commit f7cfad4592
@@ -172,9 +172,16 @@ fn temp_path(path: &Path) -> PathBuf {
.unwrap_or_else(|| "registry.json".to_string());
// 临时文件名必须**每次写都不同**:只用 pid 的话,同一进程里两个并发写共用同一个临时文件,
// 一个会截断另一个正在写的内容,rename 也会互相抢。进程内原子计数器保证不重名。
//
// 计数器从 0 重来,所以还要带上「现在」:上一次进程崩在 `create_new` 与 rename 之间时,
// 会留下 `.tmp` 残骸;系统把同一个 pid 再分给新进程时,只靠 pid + 序号会撞上那份残骸,
// 而 `create_new` 会直接以 already-exists 失败。纳秒时间戳让重启后的第一次写也不再撞名。
let sequence = TEMP_FILE_SEQUENCE.fetch_add(1, Ordering::Relaxed);
let stamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |elapsed| elapsed.as_nanos());
path.with_file_name(format!(
".{file_name}.{}.{sequence}.tmp",
".{file_name}.{}.{sequence}.{stamp}.tmp",
std::process::id()
))
}