导出注册表临时文件名按写入序号唯一化

- registry.rs 的 temp_path 在 pid 之外加入进程内原子自增序号,同一注册表路径的并发写不再共用同一个 .tmp 文件
This commit is contained in:
2026-10-06 18:49:00 +08:00
parent 411771af2f
commit 32d77a0ccd
@@ -8,6 +8,7 @@ use std::fmt;
use std::fs;
use std::io::Write as _;
use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering;
use serde::de::DeserializeOwned;
use serde::Serialize;
@@ -150,9 +151,18 @@ fn temp_path(path: &Path) -> PathBuf {
.file_name()
.map(|name| name.to_string_lossy().into_owned())
.unwrap_or_else(|| "registry.json".to_string());
path.with_file_name(format!(".{file_name}.{}.tmp", std::process::id()))
// 临时文件名必须**每次写都不同**:只用 pid 的话,同一进程里两个并发写共用同一个临时文件,
// 一个会截断另一个正在写的内容,rename 也会互相抢。进程内原子计数器保证不重名。
let sequence = TEMP_FILE_SEQUENCE.fetch_add(1, Ordering::Relaxed);
path.with_file_name(format!(
".{file_name}.{}.{sequence}.tmp",
std::process::id()
))
}
/// 同进程内临时文件名的序号,见 [`temp_path`]。
static TEMP_FILE_SEQUENCE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
#[cfg(test)]
mod tests {
use super::*;