From 51ef1329beaee5be5e87f88bfd00d887df19d3f8 Mon Sep 17 00:00:00 2001 From: Tunglies Date: Fri, 11 Apr 2025 17:47:08 +0800 Subject: [PATCH] Refactor async runtime usage with AsyncHandler wrapper --- src-tauri/src/cmd/app.rs | 2 +- src-tauri/src/cmd/clash.rs | 7 ++-- src-tauri/src/core/hotkey.rs | 7 ++-- src-tauri/src/core/tray/mod.rs | 2 +- src-tauri/src/feat/window.rs | 55 +++++++++++++------------- src-tauri/src/lib.rs | 4 +- src-tauri/src/process/async_handler.rs | 16 ++++++++ 7 files changed, 55 insertions(+), 38 deletions(-) diff --git a/src-tauri/src/cmd/app.rs b/src-tauri/src/cmd/app.rs index f428069f..5bc4f518 100644 --- a/src-tauri/src/cmd/app.rs +++ b/src-tauri/src/cmd/app.rs @@ -49,7 +49,7 @@ pub fn open_devtools(app_handle: tauri::AppHandle) { /// 退出应用 #[tauri::command] pub fn exit_app() { - feat::quit(Some(0)); + feat::quit(); } /// 重启应用 diff --git a/src-tauri/src/cmd/clash.rs b/src-tauri/src/cmd/clash.rs index 8f61f0f9..e07f84e9 100644 --- a/src-tauri/src/cmd/clash.rs +++ b/src-tauri/src/cmd/clash.rs @@ -1,5 +1,7 @@ use super::CmdResult; -use crate::{config::*, core::*, feat, module::mihomo::MihomoManager, wrap_err}; +use crate::{ + config::*, core::*, feat, module::mihomo::MihomoManager, process::AsyncHandler, wrap_err, +}; use serde_yaml::Mapping; /// 复制Clash环境变量 @@ -104,10 +106,9 @@ pub fn apply_dns_config(apply: bool) -> CmdResult { core::{handle, CoreManager}, utils::dirs, }; - use tauri::async_runtime; // 使用spawn来处理异步操作 - async_runtime::spawn(async move { + AsyncHandler::spawn(move || async move { if apply { // 读取DNS配置文件 let dns_path = match dirs::app_home_dir() { diff --git a/src-tauri/src/core/hotkey.rs b/src-tauri/src/core/hotkey.rs index 3379078e..aafaca35 100755 --- a/src-tauri/src/core/hotkey.rs +++ b/src-tauri/src/core/hotkey.rs @@ -3,13 +3,14 @@ use crate::{ core::handle, feat, logging, logging_error, module::lightweight::entry_lightweight_mode, + process::AsyncHandler, utils::{logging::Type, resolve}, }; use anyhow::{bail, Result}; use once_cell::sync::OnceCell; use parking_lot::Mutex; use std::{collections::HashMap, sync::Arc}; -use tauri::{async_runtime, Manager}; +use tauri::Manager; use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, ShortcutState}; pub struct Hotkey { @@ -153,7 +154,7 @@ impl Hotkey { ); // 使用 spawn_blocking 来确保在正确的线程上执行 - async_runtime::spawn_blocking(|| { + AsyncHandler::spawn_blocking(|| { logging!(debug, Type::Hotkey, "Toggle dashboard window visibility"); // 检查窗口是否存在 @@ -195,7 +196,7 @@ impl Hotkey { "toggle_system_proxy" => || feat::toggle_system_proxy(), "toggle_tun_mode" => || feat::toggle_tun_mode(None), "entry_lightweight_mode" => || entry_lightweight_mode(), - "quit" => || feat::quit(Some(0)), + "quit" => || feat::quit(), #[cfg(target_os = "macos")] "hide" => || feat::hide(), diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index d1afa6c5..274ba672 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -691,7 +691,7 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) { "restart_app" => feat::restart_app(), "entry_lightweight_mode" => entry_lightweight_mode(), "quit" => { - feat::quit(Some(0)); + feat::quit(); } id if id.starts_with("profiles_") => { let profile_index = &id["profiles_".len()..]; diff --git a/src-tauri/src/feat/window.rs b/src-tauri/src/feat/window.rs index 3a9f7161..d44b0a38 100644 --- a/src-tauri/src/feat/window.rs +++ b/src-tauri/src/feat/window.rs @@ -50,7 +50,7 @@ pub fn open_or_close_dashboard() { } /// 优化的应用退出函数 -pub fn quit(code: Option) { +pub fn quit() { log::debug!(target: "app", "启动退出流程"); // 获取应用句柄并设置退出标志 @@ -64,47 +64,46 @@ pub fn quit(code: Option) { // 在单独线程中处理资源清理,避免阻塞主线程 std::thread::spawn(move || { - // 使用tokio运行时执行异步清理任务 - tauri::async_runtime::block_on(async { - // 使用超时机制处理清理操作 - use tokio::time::{timeout, Duration}; - - // 1. 直接关闭TUN模式 (优先处理,通常最容易卡住) - if Config::verge().data().enable_tun_mode.unwrap_or(false) { - let disable = serde_json::json!({ + use tokio::time::{timeout, Duration}; + let rt = tokio::runtime::Runtime::new().unwrap(); + let cleanup_result = rt.block_on(async { + // 1. 处理TUN模式 + let tun_success = if Config::verge().data().enable_tun_mode.unwrap_or(false) { + let disable_tun = serde_json::json!({ "tun": { "enable": false } }); - - // 设置1秒超时 - let _ = timeout( + timeout( Duration::from_secs(1), - MihomoManager::global().patch_configs(disable), + MihomoManager::global().patch_configs(disable_tun), ) - .await; - } + .await + .is_ok() + } else { + true + }; - // 2. 并行处理系统代理和核心进程清理 - let proxy_future = timeout( + // 2. 顺序执行关键清理 + let proxy_res = timeout( Duration::from_secs(1), sysopt::Sysopt::global().reset_sysproxy(), - ); + ) + .await; - let core_future = timeout(Duration::from_secs(1), CoreManager::global().stop_core()); + let core_res = timeout(Duration::from_secs(1), CoreManager::global().stop_core()).await; - // 同时等待两个任务完成 - let _ = futures::join!(proxy_future, core_future); - - // 3. 处理macOS特定清理 + // 3. 平台特定清理 #[cfg(target_os = "macos")] - { - let _ = timeout(Duration::from_millis(500), resolve::restore_public_dns()).await; - } + let _dns_res = timeout(Duration::from_millis(500), resolve::restore_public_dns()).await; + + tun_success && proxy_res.is_ok() && core_res.is_ok() }); - // 无论清理结果如何,确保应用退出 - app_handle.exit(code.unwrap_or(0)); + app_handle.exit(match cleanup_result { + true => 0, + false => 1, + }); }); } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ee63e290..4fcd7eff 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -86,7 +86,7 @@ impl AppHandleManager { #[allow(clippy::panic)] pub fn run() { // 单例检测 - let app_exists: bool = tauri::async_runtime::block_on(async move { + let app_exists: bool = AsyncHandler::block_on(move || async move { if server::check_singleton().await.is_err() { println!("app exists"); true @@ -134,7 +134,7 @@ pub fn run() { }); }); - tauri::async_runtime::block_on(async move { + AsyncHandler::block_on(move || async move { resolve::resolve_setup(app).await; }); diff --git a/src-tauri/src/process/async_handler.rs b/src-tauri/src/process/async_handler.rs index c5a809d4..104e75c7 100644 --- a/src-tauri/src/process/async_handler.rs +++ b/src-tauri/src/process/async_handler.rs @@ -11,4 +11,20 @@ impl AsyncHandler { { async_runtime::spawn(f()) } + + pub fn spawn_blocking(f: F) -> JoinHandle + where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, + { + async_runtime::spawn_blocking(f) + } + + pub fn block_on(f: F) -> R + where + F: FnOnce() -> Fut, + Fut: Future, + { + async_runtime::block_on(f()) + } }