性能优化
This commit is contained in:
@@ -40,7 +40,7 @@ impl Storage {
|
||||
pub fn new(data_dir: PathBuf) -> Self {
|
||||
// 确保数据目录存在(首次启动或目录被删除时自动创建)
|
||||
if let Err(e) = fs::create_dir_all(&data_dir) {
|
||||
eprintln!("[download_engine] 创建数据目录失败: {} ({})", data_dir.display(), e);
|
||||
crate::logger::log_error("download", &format!("创建数据目录失败: {} ({})", data_dir.display(), e));
|
||||
}
|
||||
let state_path = data_dir.join("engine_state.json");
|
||||
let existing = Self::load_raw(&state_path);
|
||||
@@ -68,23 +68,24 @@ impl Storage {
|
||||
Self::load_raw(&self.state_path).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// 保存状态到磁盘
|
||||
pub fn save(&self, mut state: EngineState) {
|
||||
/// 保存状态到磁盘(原子写:先写 .tmp 再 rename 覆盖,
|
||||
/// 避免进程崩溃时产生半写/截断的状态文件导致任务列表丢失)
|
||||
/// 失败返回 Err,由调用方决定是否将任务置为 Error(防止"看似已保存"的假象)。
|
||||
pub fn save(&self, mut state: EngineState) -> Result<(), String> {
|
||||
// 同步 ID 计数器
|
||||
state.next_id = self.id_counter.load(Ordering::SeqCst);
|
||||
match serde_json::to_string_pretty(&state) {
|
||||
Ok(json) => {
|
||||
// 兜底:若父目录被外部删除则在写入前重建
|
||||
if let Some(parent) = self.state_path.parent() {
|
||||
let _ = fs::create_dir_all(parent);
|
||||
}
|
||||
if let Err(e) = fs::write(&self.state_path, json) {
|
||||
eprintln!("[download_engine] 保存状态失败: {}", e);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[download_engine] 序列化状态失败: {}", e);
|
||||
}
|
||||
let json = serde_json::to_string_pretty(&state)
|
||||
.map_err(|e| format!("序列化状态失败: {}", e))?;
|
||||
// 兜底:若父目录被外部删除则在写入前重建
|
||||
if let Some(parent) = self.state_path.parent() {
|
||||
let _ = fs::create_dir_all(parent);
|
||||
}
|
||||
let tmp_path = PathBuf::from(format!("{}.tmp", self.state_path.display()));
|
||||
fs::write(&tmp_path, json).map_err(|e| format!("保存状态失败: {}", e))?;
|
||||
fs::rename(&tmp_path, &self.state_path).map_err(|e| {
|
||||
let _ = fs::remove_file(&tmp_path);
|
||||
format!("替换状态文件失败: {}", e)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user