diff --git a/package.json b/package.json index c321ee4d..74c37cc8 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "2.0.4-alpha", "license": "GPL-3.0-only", "scripts": { - "dev": "cross-env RUST_BACKTRACE=1 tauri dev --features verge-dev", + "dev": "cross-env RUST_BACKTRACE=1 tauri dev", "dev:diff": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev", "build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build", "tauri": "tauri", diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 56da7391..07ffca8d 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -10,14 +10,10 @@ use std::{sync::Arc, time::Duration}; use tauri_plugin_shell::ShellExt; use tokio::sync::Mutex; use tokio::time::sleep; -use super::process_lock::ProcessLock; -use super::health_check::HealthChecker; #[derive(Debug)] pub struct CoreManager { running: Arc>, - process_lock: Arc>>, - health_checker: HealthChecker, } impl CoreManager { @@ -25,19 +21,11 @@ impl CoreManager { static CORE_MANAGER: OnceCell = OnceCell::new(); CORE_MANAGER.get_or_init(|| CoreManager { running: Arc::new(Mutex::new(false)), - process_lock: Arc::new(Mutex::new(None)), - health_checker: HealthChecker::new(), }) } pub async fn init(&self) -> Result<()> { log::trace!("run core start"); - - // 初始化进程锁 - let process_lock = ProcessLock::new()?; - process_lock.acquire()?; - *self.process_lock.lock().await = Some(process_lock); - // 启动clash log_err!(Self::global().start_core().await); log::trace!("run core end"); @@ -68,39 +56,37 @@ impl CoreManager { /// 停止核心运行 pub async fn stop_core(&self) -> Result<()> { - log::info!(target: "app", "Stopping core"); + let mut running = self.running.lock().await; + + if !*running { + log::debug!("core is not running"); + return Ok(()); + } // 关闭tun模式 let mut disable = Mapping::new(); let mut tun = Mapping::new(); tun.insert("enable".into(), false.into()); disable.insert("tun".into(), tun.into()); - log::debug!(target: "app", "Disabling TUN mode"); - let _ = clash_api::patch_configs(&disable).await; + log::debug!(target: "app", "disable tun mode"); + log_err!(clash_api::patch_configs(&disable).await); - // 直接尝试停止服务,不预先检查状态 - log::info!(target: "app", "Attempting to stop service"); - let _ = service::stop_core_by_service().await; - - // 设置运行状态 - *self.running.lock().await = false; - - // 释放进程锁 - let mut process_lock = self.process_lock.lock().await; - if let Some(lock) = process_lock.take() { - log::info!(target: "app", "Releasing process lock"); - let _ = lock.release(); + // 服务模式 + if service::check_service().await.is_ok() { + log::info!(target: "app", "stop the core by service"); + service::stop_core_by_service().await?; } - - log::info!(target: "app", "Core stopped successfully"); + *running = false; Ok(()) } /// 启动核心 pub async fn start_core(&self) -> Result<()> { - #[cfg(not(target_os = "macos"))] - // 检查端口占用 - self.health_checker.check_ports().await?; + let mut running = self.running.lock().await; + if *running { + log::info!("core is running"); + return Ok(()); + } let config_path = Config::generate_file(ConfigType::Run)?; @@ -109,23 +95,12 @@ impl CoreManager { log::info!(target: "app", "try to run core in service mode"); service::run_core_by_service(&config_path).await?; } - - // 启动健康检查 - let checker = Arc::new(self.health_checker.clone()); - tokio::spawn(async move { - loop { - sleep(Duration::from_secs(30)).await; - if let Err(e) = checker.check_service_health().await { - log::error!(target: "app", "Health check failed: {}", e); - } - } - }); - // 流量订阅 #[cfg(target_os = "macos")] log_err!(Tray::global().subscribe_traffic().await); - *self.running.lock().await = true; + *running = true; + Ok(()) } diff --git a/src-tauri/src/core/mod.rs b/src-tauri/src/core/mod.rs index 7f00e3a7..098052b9 100644 --- a/src-tauri/src/core/mod.rs +++ b/src-tauri/src/core/mod.rs @@ -9,6 +9,5 @@ pub mod sysopt; pub mod timer; pub mod tray; pub mod win_uwp; -pub mod process_lock; -pub mod health_check; + pub use self::core::*; diff --git a/src-tauri/src/core/service.rs b/src-tauri/src/core/service.rs index 50b91fab..d4d5a93a 100644 --- a/src-tauri/src/core/service.rs +++ b/src-tauri/src/core/service.rs @@ -161,49 +161,20 @@ pub async fn reinstall_service() -> Result<()> { /// check the windows service status pub async fn check_service() -> Result { - log::info!(target: "app", "Checking service status"); - println!("Checking service status"); - let url = format!("{SERVICE_URL}/get_clash"); - log::debug!(target: "app", "Sending request to {}", url); - println!("Sending request to {}", url); - - let client = reqwest::ClientBuilder::new() + let response = reqwest::ClientBuilder::new() .no_proxy() .timeout(Duration::from_secs(3)) - .build()?; - - // 重试3次 - for i in 0..3 { - match client.get(&url).send().await { - Ok(resp) => { - match resp.json::().await { - Ok(json) => { - log::info!(target: "app", "Service check response: {:?}", json); - println!("Service check response: {:?}", json); - return Ok(json); - } - Err(e) => { - log::error!(target: "app", "Failed to parse service response (attempt {}): {}", i + 1, e); - println!("Failed to parse service response (attempt {}): {}", i + 1, e); - if i == 2 { - return Err(e.into()); - } - } - } - } - Err(e) => { - log::error!(target: "app", "Failed to connect to service (attempt {}): {}", i + 1, e); - println!("Failed to connect to service (attempt {}): {}", i + 1, e); - if i == 2 { - return Err(e.into()); - } - } - } - tokio::time::sleep(Duration::from_millis(500)).await; - } - - bail!("Failed to check service after 3 attempts") + .build()? + .get(url) + .send() + .await + .context("failed to connect to the Clash Verge Service")? + .json::() + .await + .context("failed to parse the Clash Verge Service response")?; + + Ok(response) } /// start the clash by service @@ -248,32 +219,14 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> { /// stop the clash by service pub(super) async fn stop_core_by_service() -> Result<()> { - log::info!(target: "app", "Attempting to stop core through service"); - let url = format!("{SERVICE_URL}/stop_clash"); - let client = reqwest::ClientBuilder::new() + let _ = reqwest::ClientBuilder::new() .no_proxy() - .timeout(Duration::from_secs(3)) - .build()?; - - // 重试2次 - for i in 0..2 { - match client.post(&url).send().await { - Ok(_) => { - log::info!(target: "app", "Successfully sent stop request to service"); - // 等待服务停止 - tokio::time::sleep(Duration::from_millis(500)).await; - return Ok(()); - } - Err(e) => { - log::error!(target: "app", "Failed to send stop request (attempt {}): {}", i + 1, e); - if i == 1 { - return Err(e.into()); - } - } - } - tokio::time::sleep(Duration::from_millis(500)).await; - } - - bail!("Failed to stop service after 2 attempts") + .build()? + .post(url) + .send() + .await + .context("failed to connect to the Clash Verge Service")?; + + Ok(()) } diff --git a/src-tauri/src/feat.rs b/src-tauri/src/feat.rs index b294930a..f924b08f 100644 --- a/src-tauri/src/feat.rs +++ b/src-tauri/src/feat.rs @@ -162,41 +162,10 @@ pub fn toggle_tun_mode() { } pub fn quit(code: Option) { - println!("Starting application quit process"); - log::info!(target: "app", "Starting application quit process"); - let app_handle = handle::Handle::global().app_handle().unwrap(); handle::Handle::global().set_is_exiting(); - - // 立即关闭窗口,让用户感知到退出开始 - if let Some(window) = handle::Handle::global().get_window() { - let _ = window.close(); - } - - // 移除系统托盘图标 - if let Some(tray) = app_handle.tray_by_id("main") { - let _ = tray.set_icon(None); - } - - // 后台执行所有清理工作 - let app_handle_clone = app_handle.clone(); - tauri::async_runtime::block_on(async move { - // 1. 发送停止内核指令 - let _ = CoreManager::global().stop_core().await; - - // 2. 重置系统代理 - resolve::resolve_reset(); - - // 3. 保存窗口状态 - let _ = app_handle_clone.save_window_state(StateFlags::default()); - - println!("Cleanup tasks completed in background"); - log::info!(target: "app", "Cleanup tasks completed in background"); - }); - - // 主线程退出 - println!("Exiting application with code: {:?}", code); - log::info!(target: "app", "Exiting application with code: {:?}", code); + resolve::resolve_reset(); + log_err!(handle::Handle::global().get_window().unwrap().close()); app_handle.exit(code.unwrap_or(0)); } diff --git a/src-tauri/src/utils/init.rs b/src-tauri/src/utils/init.rs index 4d2f7690..b46d1d0c 100644 --- a/src-tauri/src/utils/init.rs +++ b/src-tauri/src/utils/init.rs @@ -15,67 +15,47 @@ use tauri_plugin_shell::ShellExt; /// initialize this instance's log file fn init_log() -> Result<()> { - println!("Starting log initialization..."); - let log_dir = dirs::app_logs_dir()?; if !log_dir.exists() { - println!("Creating log directory: {:?}", log_dir); let _ = fs::create_dir_all(&log_dir); } let log_level = Config::verge().data().get_log_level(); - println!("Current log level: {:?}", log_level); - if log_level == LevelFilter::Off { - println!("Logging is disabled"); return Ok(()); } + let local_time = Local::now().format("%Y-%m-%d-%H%M").to_string(); + let log_file = format!("{}.log", local_time); + let log_file = log_dir.join(log_file); + let log_pattern = match log_level { LevelFilter::Trace => "{d(%Y-%m-%d %H:%M:%S)} {l} [{M}] - {m}{n}", _ => "{d(%Y-%m-%d %H:%M:%S)} {l} - {m}{n}", }; let encode = Box::new(PatternEncoder::new(log_pattern)); - let stdout = ConsoleAppender::builder().encoder(encode.clone()).build(); - let local_time = Local::now().format("%Y-%m-%d-%H%M").to_string(); - let log_file = format!("{}.log", local_time); - let log_file = log_dir.join(log_file); - println!("Log file path: {:?}", log_file); - + let stdout = ConsoleAppender::builder().encoder(encode.clone()).build(); let tofile = FileAppender::builder().encoder(encode).build(log_file)?; let mut logger_builder = Logger::builder(); let mut root_builder = Root::builder(); let log_more = log_level == LevelFilter::Trace || log_level == LevelFilter::Debug; - logger_builder = logger_builder.appenders(["stdout", "file"]); - root_builder = root_builder.appender("stdout"); + + logger_builder = logger_builder.appenders(["file"]); if log_more { - root_builder = root_builder.appender("file"); + root_builder = root_builder.appenders(["file"]); } - println!("Building log config..."); - let config = log4rs::config::Config::builder() + let (config, _) = log4rs::config::Config::builder() .appender(Appender::builder().build("stdout", Box::new(stdout))) .appender(Appender::builder().build("file", Box::new(tofile))) .logger(logger_builder.additive(false).build("app", log_level)) - .build(root_builder.build(log_level)) - .map_err(|e| anyhow::anyhow!("Failed to build log config: {}", e))?; + .build_lossy(root_builder.build(log_level)); - println!("Initializing log config..."); - match log4rs::init_config(config) { - Ok(_) => println!("Log system initialized successfully"), - Err(e) => println!("Failed to initialize log system: {}", e), - } - - // 测试日志系统 - log::error!(target: "app", "Test error log message"); - log::warn!(target: "app", "Test warning log message"); - log::info!(target: "app", "Test info log message"); - log::debug!(target: "app", "Test debug log message"); - log::trace!(target: "app", "Test trace log message"); + log4rs::init_config(config)?; Ok(()) }