From 786c981fe0202adfbdfb4221a10be195a8b79bac Mon Sep 17 00:00:00 2001 From: xmk23333 Date: Mon, 20 Oct 2025 13:26:24 +0800 Subject: [PATCH] refactor: improve error handling in AppDataProvider and enhance configuration update logic in CoreManager --- src-tauri/src/core/core.rs | 73 +++++++++++++++++++---------- src-tauri/src/lib.rs | 3 +- src-tauri/src/utils/resolve/mod.rs | 21 +++++---- src-tauri/src/utils/server.rs | 2 +- src/providers/app-data-provider.tsx | 3 ++ 5 files changed, 67 insertions(+), 35 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 9f6aa03dc..9c00686fe 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -27,12 +27,12 @@ use flexi_logger::DeferredNow; use log::Level; use parking_lot::Mutex; use std::collections::VecDeque; -#[cfg(target_os = "windows")] use std::time::Instant; use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Duration}; use tauri_plugin_mihomo::Error as MihomoError; use tauri_plugin_shell::ShellExt; use tokio::time::sleep; +use tokio::sync::Semaphore; // TODO: // - 重构,提升模式切换速度 @@ -42,6 +42,8 @@ use tokio::time::sleep; pub struct CoreManager { running: Arc>, child_sidecar: Arc>>, + update_semaphore: Arc, + last_update: Arc>>, } /// 内核运行模式 @@ -87,36 +89,57 @@ impl CoreManager { /// 更新proxies等配置 pub async fn update_config(&self) -> Result<(bool, String)> { - // 检查程序是否正在退出,如果是则跳过完整验证流程 if handle::Handle::global().is_exiting() { logging!(info, Type::Config, "应用正在退出,跳过验证"); return Ok((true, String::new())); } - // 1. 先生成新的配置内容 - logging!(info, Type::Config, "生成新的配置内容"); - Config::generate().await?; - - // 2. 验证配置 - match CoreConfigValidator::global().validate_config().await { - Ok((true, _)) => { - // 4. 验证通过后,生成正式的运行时配置 - logging!(info, Type::Config, "配置验证通过, 生成运行时配置"); - let run_path = Config::generate_file(ConfigType::Run).await?; - self.put_configs_force(run_path).await?; - Ok((true, String::new())) - } - Ok((false, error_msg)) => { - logging!(warn, Type::Config, "配置验证失败: {}", error_msg); - Config::runtime().await.discard(); - Ok((false, error_msg)) - } - Err(e) => { - logging!(warn, Type::Config, "验证过程发生错误: {}", e); - Config::runtime().await.discard(); - Err(e) + let now = Instant::now(); + { + let mut last = self.last_update.lock(); + if let Some(last_time) = *last { + if now.duration_since(last_time) < Duration::from_millis(500) { + logging!(debug, Type::Config, "防抖:跳过重复的配置更新请求"); + return Ok((true, String::new())); + } } + *last = Some(now); } + + let permit = match self.update_semaphore.try_acquire() { + Ok(p) => p, + Err(_) => { + logging!(debug, Type::Config, "配置更新已在进行中,跳过"); + return Ok((true, String::new())); + } + }; + + let result = async { + logging!(info, Type::Config, "生成新的配置内容"); + Config::generate().await?; + + match CoreConfigValidator::global().validate_config().await { + Ok((true, _)) => { + logging!(info, Type::Config, "配置验证通过, 生成运行时配置"); + let run_path = Config::generate_file(ConfigType::Run).await?; + self.put_configs_force(run_path).await?; + Ok((true, String::new())) + } + Ok((false, error_msg)) => { + logging!(warn, Type::Config, "配置验证失败: {}", error_msg); + Config::runtime().await.discard(); + Ok((false, error_msg)) + } + Err(e) => { + logging!(warn, Type::Config, "验证过程发生错误: {}", e); + Config::runtime().await.discard(); + Err(e) + } + } + }.await; + + drop(permit); + result } pub async fn put_configs_force(&self, path_buf: PathBuf) -> Result<()> { let run_path_str = dirs::path_to_str(&path_buf).map_err(|e| { @@ -628,6 +651,8 @@ impl Default for CoreManager { CoreManager { running: Arc::new(Mutex::new(RunningMode::NotRunning)), child_sidecar: Arc::new(Mutex::new(None)), + update_semaphore: Arc::new(Semaphore::new(1)), + last_update: Arc::new(Mutex::new(None)), } } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 66d60ef6e..e5891e1fc 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -266,10 +266,11 @@ pub fn run() { logging!(info, Type::Setup, "执行主要设置操作..."); resolve::resolve_setup_handle(); + // 异步任务启动,不等待完成 resolve::resolve_setup_async(); resolve::resolve_setup_sync(); - logging!(info, Type::Setup, "初始化完成,继续执行"); + logging!(info, Type::Setup, "初始化已启动,继续执行"); Ok(()) }) .invoke_handler(app_init::generate_handlers()); diff --git a/src-tauri/src/utils/resolve/mod.rs b/src-tauri/src/utils/resolve/mod.rs index 8218f7cb1..a9ae61013 100644 --- a/src-tauri/src/utils/resolve/mod.rs +++ b/src-tauri/src/utils/resolve/mod.rs @@ -53,18 +53,21 @@ pub fn resolve_setup_async() { futures::join!(init_work_config(), init_resources(), init_startup_script(),); - // 确保配置完全初始化后再启动核心管理器 init_verge_config().await; - // 添加配置验证,确保运行时配置已正确生成 Config::verify_config_initialization().await; - init_service_manager().await; - init_core_manager().await; + // 优先创建窗口,提升启动体验 + init_window().await; - init_system_proxy().await; - AsyncHandler::spawn_blocking(|| { - init_system_proxy_guard(); + // 后台异步初始化核心,不阻塞窗口显示 + let core_init = AsyncHandler::spawn(|| async { + init_service_manager().await; + init_core_manager().await; + init_system_proxy().await; + AsyncHandler::spawn_blocking(|| { + init_system_proxy_guard(); + }); }); let tray_and_refresh = async { @@ -73,7 +76,7 @@ pub fn resolve_setup_async() { }; futures::join!( - init_window(), + core_init, tray_and_refresh, init_timer(), init_hotkey(), @@ -83,7 +86,7 @@ pub fn resolve_setup_async() { }); let elapsed = start_time.elapsed(); - logging!(info, Type::Setup, "异步设置任务完成,耗时: {:?}", elapsed); + logging!(info, Type::Setup, "异步设置任务启动完成,耗时: {:?}", elapsed); if elapsed.as_secs() > 10 { logging!(warn, Type::Setup, "异步设置任务耗时较长({:?})", elapsed); diff --git a/src-tauri/src/utils/server.rs b/src-tauri/src/utils/server.rs index 6888a8dc2..3902688b3 100644 --- a/src-tauri/src/utils/server.rs +++ b/src-tauri/src/utils/server.rs @@ -29,7 +29,7 @@ pub async fn check_singleton() -> Result<()> { let port = IVerge::get_singleton_port(); if !local_port_available(port) { let client = ClientBuilder::new() - .timeout(Duration::from_millis(1000)) + .timeout(Duration::from_millis(500)) .build()?; let argvs: Vec = std::env::args().collect(); if argvs.len() > 1 { diff --git a/src/providers/app-data-provider.tsx b/src/providers/app-data-provider.tsx index 2c17b849e..9511b795e 100644 --- a/src/providers/app-data-provider.tsx +++ b/src/providers/app-data-provider.tsx @@ -35,6 +35,9 @@ export const AppDataProvider = ({ suspense: false, errorRetryCount: 2, dedupingInterval: 3000, + onError: (err) => { + console.warn("[DataProvider] 代理数据获取失败:", err); + }, }, );