fix(core): resolve aria2c daemon leak and tokio io blocking

This commit patches a critical resource leak by managing the aria2c child process using an idiomatic RAII Drop guard inside Tauri's managed state. It also purges the legacy `open` crate from Cargo.toml in favor of tauri-plugin-opener, and fully migrates all asynchronous file system operations to tokio::fs to unblock the Tokio async runtime.
This commit is contained in:
NimBold
2026-06-13 22:49:37 +03:30
parent ae19f69e7b
commit 4ec1c4fdf6
3 changed files with 23 additions and 9 deletions
-1
View File
@@ -4418,7 +4418,6 @@ dependencies = [
"keepawake",
"keyring",
"objc",
"open",
"regex 1.12.4",
"reqwest 0.12.28",
"rusqlite",
-1
View File
@@ -40,7 +40,6 @@ tower-http = { version = "0.6.11", features = ["cors"] }
sysproxy = "0.3.0"
semver = "1.0.28"
keepawake = "0.6.0"
open = "5.3.5"
system_shutdown = "4.1.0"
tokio-tungstenite = "0.29.0"
futures-util = { version = "0.3.32", features = ["sink"] }
+23 -7
View File
@@ -297,9 +297,10 @@ async fn test_deno(app_handle: tauri::AppHandle) -> Result<String, String> {
}
#[tauri::command]
async fn open_file(path: String) -> Result<(), String> {
async fn open_file(app: tauri::AppHandle, path: String) -> Result<(), String> {
println!("open_file called for path: {}", path);
open::that(&path).map_err(|e| format!("Failed to open file: {}", e))
use tauri_plugin_opener::OpenerExt;
app.opener().open_path(&path, None::<String>).map_err(|e| format!("Failed to open file: {}", e))
}
#[tauri::command]
@@ -313,6 +314,18 @@ use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, RwLock};
struct Aria2DaemonGuard(std::sync::Mutex<Option<std::process::Child>>);
impl Drop for Aria2DaemonGuard {
fn drop(&mut self) {
if let Ok(mut lock) = self.0.lock() {
if let Some(mut child) = lock.take() {
let _ = child.kill();
}
}
}
}
mod parity;
pub mod error;
pub use error::AppError;
@@ -413,7 +426,7 @@ async fn start_download(
}
if !resolved_dest.exists() {
let _ = std::fs::create_dir_all(&resolved_dest);
let _ = tokio::fs::create_dir_all(&resolved_dest).await;
}
let gid: String = id.replace("-", "").chars().take(16).collect();
@@ -584,7 +597,7 @@ pub(crate) async fn start_media_download_internal(
}
if !resolved_dest.exists() {
let _ = std::fs::create_dir_all(&resolved_dest);
let _ = tokio::fs::create_dir_all(&resolved_dest).await;
}
let out_path = resolved_dest.join(&filename);
@@ -845,12 +858,12 @@ async fn remove_download(state: tauri::State<'_, AppState>, id: String, filepath
if !path.is_empty() {
let p = std::path::Path::new(&path);
if p.exists() {
let _ = std::fs::remove_file(p);
let _ = tokio::fs::remove_file(p).await;
}
let aria2_path = format!("{}.aria2", path);
let p_aria2 = std::path::Path::new(&aria2_path);
if p_aria2.exists() {
let _ = std::fs::remove_file(p_aria2);
let _ = tokio::fs::remove_file(p_aria2).await;
}
}
}
@@ -1210,7 +1223,10 @@ pub fn run() {
.arg("--check-certificate=false");
match cmd.spawn() {
Ok(_) => println!("Spawned global aria2c daemon on port {}", aria2_port),
Ok(child) => {
println!("Spawned global aria2c daemon on port {}", aria2_port);
app.manage(Aria2DaemonGuard(std::sync::Mutex::new(Some(child))));
}
Err(e) => eprintln!("Failed to spawn aria2c daemon: {}", e),
}