mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
refactor: improve error handling in AppDataProvider and enhance configuration update logic in CoreManager
This commit is contained in:
@@ -27,12 +27,12 @@ use flexi_logger::DeferredNow;
|
|||||||
use log::Level;
|
use log::Level;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Duration};
|
use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Duration};
|
||||||
use tauri_plugin_mihomo::Error as MihomoError;
|
use tauri_plugin_mihomo::Error as MihomoError;
|
||||||
use tauri_plugin_shell::ShellExt;
|
use tauri_plugin_shell::ShellExt;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
use tokio::sync::Semaphore;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - 重构,提升模式切换速度
|
// - 重构,提升模式切换速度
|
||||||
@@ -42,6 +42,8 @@ use tokio::time::sleep;
|
|||||||
pub struct CoreManager {
|
pub struct CoreManager {
|
||||||
running: Arc<Mutex<RunningMode>>,
|
running: Arc<Mutex<RunningMode>>,
|
||||||
child_sidecar: Arc<Mutex<Option<CommandChildGuard>>>,
|
child_sidecar: Arc<Mutex<Option<CommandChildGuard>>>,
|
||||||
|
update_semaphore: Arc<Semaphore>,
|
||||||
|
last_update: Arc<Mutex<Option<Instant>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 内核运行模式
|
/// 内核运行模式
|
||||||
@@ -87,20 +89,37 @@ impl CoreManager {
|
|||||||
|
|
||||||
/// 更新proxies等配置
|
/// 更新proxies等配置
|
||||||
pub async fn update_config(&self) -> Result<(bool, String)> {
|
pub async fn update_config(&self) -> Result<(bool, String)> {
|
||||||
// 检查程序是否正在退出,如果是则跳过完整验证流程
|
|
||||||
if handle::Handle::global().is_exiting() {
|
if handle::Handle::global().is_exiting() {
|
||||||
logging!(info, Type::Config, "应用正在退出,跳过验证");
|
logging!(info, Type::Config, "应用正在退出,跳过验证");
|
||||||
return Ok((true, String::new()));
|
return Ok((true, String::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. 先生成新的配置内容
|
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, "生成新的配置内容");
|
logging!(info, Type::Config, "生成新的配置内容");
|
||||||
Config::generate().await?;
|
Config::generate().await?;
|
||||||
|
|
||||||
// 2. 验证配置
|
|
||||||
match CoreConfigValidator::global().validate_config().await {
|
match CoreConfigValidator::global().validate_config().await {
|
||||||
Ok((true, _)) => {
|
Ok((true, _)) => {
|
||||||
// 4. 验证通过后,生成正式的运行时配置
|
|
||||||
logging!(info, Type::Config, "配置验证通过, 生成运行时配置");
|
logging!(info, Type::Config, "配置验证通过, 生成运行时配置");
|
||||||
let run_path = Config::generate_file(ConfigType::Run).await?;
|
let run_path = Config::generate_file(ConfigType::Run).await?;
|
||||||
self.put_configs_force(run_path).await?;
|
self.put_configs_force(run_path).await?;
|
||||||
@@ -117,6 +136,10 @@ impl CoreManager {
|
|||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.await;
|
||||||
|
|
||||||
|
drop(permit);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
pub async fn put_configs_force(&self, path_buf: PathBuf) -> 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| {
|
let run_path_str = dirs::path_to_str(&path_buf).map_err(|e| {
|
||||||
@@ -628,6 +651,8 @@ impl Default for CoreManager {
|
|||||||
CoreManager {
|
CoreManager {
|
||||||
running: Arc::new(Mutex::new(RunningMode::NotRunning)),
|
running: Arc::new(Mutex::new(RunningMode::NotRunning)),
|
||||||
child_sidecar: Arc::new(Mutex::new(None)),
|
child_sidecar: Arc::new(Mutex::new(None)),
|
||||||
|
update_semaphore: Arc::new(Semaphore::new(1)),
|
||||||
|
last_update: Arc::new(Mutex::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,10 +266,11 @@ pub fn run() {
|
|||||||
logging!(info, Type::Setup, "执行主要设置操作...");
|
logging!(info, Type::Setup, "执行主要设置操作...");
|
||||||
|
|
||||||
resolve::resolve_setup_handle();
|
resolve::resolve_setup_handle();
|
||||||
|
// 异步任务启动,不等待完成
|
||||||
resolve::resolve_setup_async();
|
resolve::resolve_setup_async();
|
||||||
resolve::resolve_setup_sync();
|
resolve::resolve_setup_sync();
|
||||||
|
|
||||||
logging!(info, Type::Setup, "初始化完成,继续执行");
|
logging!(info, Type::Setup, "初始化已启动,继续执行");
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(app_init::generate_handlers());
|
.invoke_handler(app_init::generate_handlers());
|
||||||
|
|||||||
@@ -53,19 +53,22 @@ pub fn resolve_setup_async() {
|
|||||||
|
|
||||||
futures::join!(init_work_config(), init_resources(), init_startup_script(),);
|
futures::join!(init_work_config(), init_resources(), init_startup_script(),);
|
||||||
|
|
||||||
// 确保配置完全初始化后再启动核心管理器
|
|
||||||
init_verge_config().await;
|
init_verge_config().await;
|
||||||
|
|
||||||
// 添加配置验证,确保运行时配置已正确生成
|
|
||||||
Config::verify_config_initialization().await;
|
Config::verify_config_initialization().await;
|
||||||
|
|
||||||
|
// 优先创建窗口,提升启动体验
|
||||||
|
init_window().await;
|
||||||
|
|
||||||
|
// 后台异步初始化核心,不阻塞窗口显示
|
||||||
|
let core_init = AsyncHandler::spawn(|| async {
|
||||||
init_service_manager().await;
|
init_service_manager().await;
|
||||||
init_core_manager().await;
|
init_core_manager().await;
|
||||||
|
|
||||||
init_system_proxy().await;
|
init_system_proxy().await;
|
||||||
AsyncHandler::spawn_blocking(|| {
|
AsyncHandler::spawn_blocking(|| {
|
||||||
init_system_proxy_guard();
|
init_system_proxy_guard();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
let tray_and_refresh = async {
|
let tray_and_refresh = async {
|
||||||
init_tray().await;
|
init_tray().await;
|
||||||
@@ -73,7 +76,7 @@ pub fn resolve_setup_async() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
futures::join!(
|
futures::join!(
|
||||||
init_window(),
|
core_init,
|
||||||
tray_and_refresh,
|
tray_and_refresh,
|
||||||
init_timer(),
|
init_timer(),
|
||||||
init_hotkey(),
|
init_hotkey(),
|
||||||
@@ -83,7 +86,7 @@ pub fn resolve_setup_async() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let elapsed = start_time.elapsed();
|
let elapsed = start_time.elapsed();
|
||||||
logging!(info, Type::Setup, "异步设置任务完成,耗时: {:?}", elapsed);
|
logging!(info, Type::Setup, "异步设置任务启动完成,耗时: {:?}", elapsed);
|
||||||
|
|
||||||
if elapsed.as_secs() > 10 {
|
if elapsed.as_secs() > 10 {
|
||||||
logging!(warn, Type::Setup, "异步设置任务耗时较长({:?})", elapsed);
|
logging!(warn, Type::Setup, "异步设置任务耗时较长({:?})", elapsed);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ pub async fn check_singleton() -> Result<()> {
|
|||||||
let port = IVerge::get_singleton_port();
|
let port = IVerge::get_singleton_port();
|
||||||
if !local_port_available(port) {
|
if !local_port_available(port) {
|
||||||
let client = ClientBuilder::new()
|
let client = ClientBuilder::new()
|
||||||
.timeout(Duration::from_millis(1000))
|
.timeout(Duration::from_millis(500))
|
||||||
.build()?;
|
.build()?;
|
||||||
let argvs: Vec<String> = std::env::args().collect();
|
let argvs: Vec<String> = std::env::args().collect();
|
||||||
if argvs.len() > 1 {
|
if argvs.len() > 1 {
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ export const AppDataProvider = ({
|
|||||||
suspense: false,
|
suspense: false,
|
||||||
errorRetryCount: 2,
|
errorRetryCount: 2,
|
||||||
dedupingInterval: 3000,
|
dedupingInterval: 3000,
|
||||||
|
onError: (err) => {
|
||||||
|
console.warn("[DataProvider] 代理数据获取失败:", err);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user