refactor: improve error handling in AppDataProvider and enhance configuration update logic in CoreManager

This commit is contained in:
xmk23333
2025-10-20 13:26:24 +08:00
parent b77cc012e1
commit 786c981fe0
5 changed files with 67 additions and 35 deletions

View File

@@ -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<Mutex<RunningMode>>,
child_sidecar: Arc<Mutex<Option<CommandChildGuard>>>,
update_semaphore: Arc<Semaphore>,
last_update: Arc<Mutex<Option<Instant>>>,
}
/// 内核运行模式
@@ -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)),
}
}
}

View File

@@ -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());

View File

@@ -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);

View File

@@ -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<String> = std::env::args().collect();
if argvs.len() > 1 {