fix(windows): persist adaptive mirror history

This commit is contained in:
NimBold
2026-08-09 04:21:15 +03:30
parent 3b7c454ec7
commit 5797db27c5
3 changed files with 43 additions and 0 deletions
+1
View File
@@ -460,6 +460,7 @@ try {
smokeFailure = new Error(`${error.message}${detail ? `\n${detail}` : ''}`);
} finally {
try {
if (process.platform === 'win32') fs.rmSync(serverStatPath, { force: true });
await stop(child, rpcPort, secret);
if (smokePassed) {
const stat = fs.readFileSync(serverStatPath, 'utf8');
+4
View File
@@ -3115,6 +3115,10 @@ async fn shutdown_aria2_daemon(app_handle: tauri::AppHandle) {
if let Some(state) = app_handle.try_state::<AppState>() {
let port = state.aria2_port.load(Ordering::Relaxed);
if port != 0 {
#[cfg(target_os = "windows")]
if let Err(error) = state.storage_layout.prepare_aria2_server_stat_for_replace() {
log::warn!("adaptive mirror history cannot be replaced on shutdown: {error}");
}
let shutdown = tokio::time::timeout(
std::time::Duration::from_secs(2),
rpc_call(port, &state.aria2_secret, "aria2.shutdown", serde_json::json!([])),
+38
View File
@@ -228,6 +228,26 @@ impl StorageLayout {
}
Ok(path)
}
/// The MSVC build of Aria2 uses C `rename`, which cannot replace an
/// existing destination on Windows. Remove only the already-validated,
/// app-owned regular cache immediately before graceful shutdown so
/// Aria2's `__temp` file can be renamed into place.
pub fn prepare_aria2_server_stat_for_replace(&self) -> Result<(), String> {
let path = self.aria2_server_stat_path();
match std::fs::symlink_metadata(&path) {
Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_file() => {
Err("Aria2 server-stat cache replacement target is not a regular file".to_string())
}
Ok(_) => std::fs::remove_file(&path).map_err(|error| {
format!("failed to prepare Aria2 server-stat replacement: {error}")
}),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(error) => Err(format!(
"failed to inspect Aria2 server-stat replacement target: {error}"
)),
}
}
}
fn aria2_server_stat_is_valid(contents: &str) -> bool {
@@ -395,6 +415,23 @@ mod tests {
}
}
#[test]
fn aria2_server_stat_replacement_removes_only_the_managed_regular_cache() {
let root = TempDir::new().unwrap();
let layout = test_layout(root.path());
layout.prepare_aria2_dht_paths().unwrap();
let path = layout.prepare_aria2_server_stat_path().unwrap();
fs::write(
&path,
"host=mirror.example, protocol=https, dl_speed=1, last_updated=1, status=OK\n",
)
.unwrap();
layout.prepare_aria2_server_stat_for_replace().unwrap();
assert!(!path.exists());
layout.prepare_aria2_server_stat_for_replace().unwrap();
}
#[cfg(unix)]
#[test]
fn aria2_server_stat_cache_rejects_symlink_output() {
@@ -411,6 +448,7 @@ mod tests {
.unwrap();
assert!(layout.prepare_aria2_server_stat_path().is_err());
assert!(layout.prepare_aria2_server_stat_for_replace().is_err());
}
#[cfg(unix)]