style: clean up whitespace and improve code formatting across multiple files

This commit is contained in:
xmk23333
2025-10-21 17:53:02 +08:00
parent 0e933597f5
commit ef3f8e1839
12 changed files with 141 additions and 85 deletions

View File

@@ -48,23 +48,23 @@ impl IClashTemp {
pub fn template() -> Self { pub fn template() -> Self {
use crate::constants::{network, tun as tun_const}; use crate::constants::{network, tun as tun_const};
let mut map = Mapping::new(); let mut map = Mapping::new();
let mut tun_config = Mapping::new(); let mut tun_config = Mapping::new();
let mut cors_map = Mapping::new(); let mut cors_map = Mapping::new();
tun_config.insert("enable".into(), false.into()); tun_config.insert("enable".into(), false.into());
tun_config.insert("stack".into(), tun_const::DEFAULT_STACK.into()); tun_config.insert("stack".into(), tun_const::DEFAULT_STACK.into());
tun_config.insert("auto-route".into(), true.into()); tun_config.insert("auto-route".into(), true.into());
tun_config.insert("strict-route".into(), false.into()); tun_config.insert("strict-route".into(), false.into());
tun_config.insert("auto-detect-interface".into(), true.into()); tun_config.insert("auto-detect-interface".into(), true.into());
tun_config.insert("dns-hijack".into(), tun_const::DNS_HIJACK.into()); tun_config.insert("dns-hijack".into(), tun_const::DNS_HIJACK.into());
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
map.insert("redir-port".into(), network::ports::DEFAULT_REDIR.into()); map.insert("redir-port".into(), network::ports::DEFAULT_REDIR.into());
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
map.insert("tproxy-port".into(), network::ports::DEFAULT_TPROXY.into()); map.insert("tproxy-port".into(), network::ports::DEFAULT_TPROXY.into());
map.insert("mixed-port".into(), network::ports::DEFAULT_MIXED.into()); map.insert("mixed-port".into(), network::ports::DEFAULT_MIXED.into());
map.insert("socks-port".into(), network::ports::DEFAULT_SOCKS.into()); map.insert("socks-port".into(), network::ports::DEFAULT_SOCKS.into());
map.insert("port".into(), network::ports::DEFAULT_HTTP.into()); map.insert("port".into(), network::ports::DEFAULT_HTTP.into());
@@ -72,7 +72,10 @@ impl IClashTemp {
map.insert("allow-lan".into(), false.into()); map.insert("allow-lan".into(), false.into());
map.insert("ipv6".into(), true.into()); map.insert("ipv6".into(), true.into());
map.insert("mode".into(), "rule".into()); map.insert("mode".into(), "rule".into());
map.insert("external-controller".into(), network::DEFAULT_EXTERNAL_CONTROLLER.into()); map.insert(
"external-controller".into(),
network::DEFAULT_EXTERNAL_CONTROLLER.into(),
);
#[cfg(unix)] #[cfg(unix)]
map.insert( map.insert(
"external-controller-unix".into(), "external-controller-unix".into(),
@@ -85,7 +88,8 @@ impl IClashTemp {
); );
map.insert("tun".into(), tun_config.into()); map.insert("tun".into(), tun_config.into());
cors_map.insert("allow-private-network".into(), true.into()); cors_map.insert("allow-private-network".into(), true.into());
cors_map.insert("allow-origins".into(), cors_map.insert(
"allow-origins".into(),
vec![ vec![
"tauri://localhost", "tauri://localhost",
"http://tauri.localhost", "http://tauri.localhost",

View File

@@ -173,8 +173,7 @@ impl Config {
return Ok::<(), BackoffError<anyhow::Error>>(()); return Ok::<(), BackoffError<anyhow::Error>>(());
} }
Config::generate().await Config::generate().await.map_err(BackoffError::transient)
.map_err(BackoffError::transient)
}; };
if let Err(e) = backoff::future::retry(backoff_strategy, operation).await { if let Err(e) = backoff::future::retry(backoff_strategy, operation).await {

View File

@@ -3,7 +3,7 @@ use std::time::Duration;
pub mod network { pub mod network {
pub const DEFAULT_PROXY_HOST: &str = "127.0.0.1"; pub const DEFAULT_PROXY_HOST: &str = "127.0.0.1";
pub const DEFAULT_EXTERNAL_CONTROLLER: &str = "127.0.0.1:9097"; pub const DEFAULT_EXTERNAL_CONTROLLER: &str = "127.0.0.1:9097";
pub mod ports { pub mod ports {
#[allow(dead_code)] #[allow(dead_code)]
pub const DEFAULT_REDIR: u16 = 7895; pub const DEFAULT_REDIR: u16 = 7895;
@@ -14,7 +14,7 @@ pub mod network {
pub const DEFAULT_HTTP: u16 = 7899; pub const DEFAULT_HTTP: u16 = 7899;
#[allow(dead_code)] #[allow(dead_code)]
pub const DEFAULT_EXTERNAL_CONTROLLER: u16 = 9097; pub const DEFAULT_EXTERNAL_CONTROLLER: u16 = 9097;
#[cfg(not(feature = "verge-dev"))] #[cfg(not(feature = "verge-dev"))]
pub const SINGLETON_SERVER: u16 = 33331; pub const SINGLETON_SERVER: u16 = 33331;
#[cfg(feature = "verge-dev")] #[cfg(feature = "verge-dev")]
@@ -25,17 +25,18 @@ pub mod network {
pub mod bypass { pub mod bypass {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub const DEFAULT: &str = "localhost;127.*;192.168.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;<local>"; pub const DEFAULT: &str = "localhost;127.*;192.168.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;<local>";
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub const DEFAULT: &str = "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,::1"; pub const DEFAULT: &str =
"localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,::1";
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub const DEFAULT: &str = "127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,localhost,*.local,*.crashlytics.com,<local>"; pub const DEFAULT: &str = "127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,localhost,*.local,*.crashlytics.com,<local>";
} }
pub mod timing { pub mod timing {
use super::Duration; use super::Duration;
pub const CONFIG_UPDATE_DEBOUNCE: Duration = Duration::from_millis(500); pub const CONFIG_UPDATE_DEBOUNCE: Duration = Duration::from_millis(500);
pub const CONFIG_RELOAD_DELAY: Duration = Duration::from_millis(300); pub const CONFIG_RELOAD_DELAY: Duration = Duration::from_millis(300);
pub const PROCESS_VERIFY_DELAY: Duration = Duration::from_millis(100); pub const PROCESS_VERIFY_DELAY: Duration = Duration::from_millis(100);
@@ -44,7 +45,7 @@ pub mod timing {
pub const STARTUP_ERROR_DELAY: Duration = Duration::from_secs(2); pub const STARTUP_ERROR_DELAY: Duration = Duration::from_secs(2);
#[allow(dead_code)] #[allow(dead_code)]
pub const ERROR_BATCH_DELAY: Duration = Duration::from_millis(300); pub const ERROR_BATCH_DELAY: Duration = Duration::from_millis(300);
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub const SERVICE_WAIT_MAX: Duration = Duration::from_millis(3000); pub const SERVICE_WAIT_MAX: Duration = Duration::from_millis(3000);
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@@ -70,16 +71,16 @@ pub mod files {
pub mod process { pub mod process {
pub const VERGE_MIHOMO: &str = "verge-mihomo"; pub const VERGE_MIHOMO: &str = "verge-mihomo";
pub const VERGE_MIHOMO_ALPHA: &str = "verge-mihomo-alpha"; pub const VERGE_MIHOMO_ALPHA: &str = "verge-mihomo-alpha";
pub fn process_names() -> [&'static str; 2] { pub fn process_names() -> [&'static str; 2] {
[VERGE_MIHOMO, VERGE_MIHOMO_ALPHA] [VERGE_MIHOMO, VERGE_MIHOMO_ALPHA]
} }
#[cfg(windows)] #[cfg(windows)]
pub fn with_extension(name: &str) -> String { pub fn with_extension(name: &str) -> String {
format!("{}.exe", name) format!("{}.exe", name)
} }
#[cfg(not(windows))] #[cfg(not(windows))]
pub fn with_extension(name: &str) -> String { pub fn with_extension(name: &str) -> String {
name.to_string() name.to_string()
@@ -98,10 +99,9 @@ pub mod error_patterns {
pub mod tun { pub mod tun {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub const DEFAULT_STACK: &str = "mixed"; pub const DEFAULT_STACK: &str = "mixed";
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
pub const DEFAULT_STACK: &str = "gvisor"; pub const DEFAULT_STACK: &str = "gvisor";
pub const DNS_HIJACK: &[&str] = &["any:53"]; pub const DNS_HIJACK: &[&str] = &["any:53"];
} }

View File

@@ -413,18 +413,18 @@ impl EventDrivenProxyManager {
async fn get_expected_sys_proxy() -> Sysproxy { async fn get_expected_sys_proxy() -> Sysproxy {
use crate::constants::network; use crate::constants::network;
let (verge_mixed_port, proxy_host) = { let (verge_mixed_port, proxy_host) = {
let verge_config = Config::verge().await; let verge_config = Config::verge().await;
let verge_ref = verge_config.latest_ref(); let verge_ref = verge_config.latest_ref();
(verge_ref.verge_mixed_port, verge_ref.proxy_host.clone()) (verge_ref.verge_mixed_port, verge_ref.proxy_host.clone())
}; };
let default_port = { let default_port = {
let clash_config = Config::clash().await; let clash_config = Config::clash().await;
clash_config.latest_ref().get_mixed_port() clash_config.latest_ref().get_mixed_port()
}; };
let port = verge_mixed_port.unwrap_or(default_port); let port = verge_mixed_port.unwrap_or(default_port);
let host = proxy_host.unwrap_or_else(|| network::DEFAULT_PROXY_HOST.into()); let host = proxy_host.unwrap_or_else(|| network::DEFAULT_PROXY_HOST.into());
@@ -438,7 +438,7 @@ impl EventDrivenProxyManager {
async fn get_bypass_config() -> String { async fn get_bypass_config() -> String {
use crate::constants::bypass; use crate::constants::bypass;
let verge_config = Config::verge().await; let verge_config = Config::verge().await;
let verge = verge_config.latest_ref(); let verge = verge_config.latest_ref();
let use_default = verge.use_default_bypass.unwrap_or(true); let use_default = verge.use_default_bypass.unwrap_or(true);

View File

@@ -1,4 +1,4 @@
use crate::{APP_HANDLE, singleton, constants::timing}; use crate::{APP_HANDLE, constants::timing, singleton};
use parking_lot::RwLock; use parking_lot::RwLock;
use std::{sync::Arc, thread}; use std::{sync::Arc, thread};
use tauri::{AppHandle, Manager, WebviewWindow}; use tauri::{AppHandle, Manager, WebviewWindow};
@@ -209,4 +209,3 @@ impl Handle {
let _ = self.set_activation_policy(tauri::ActivationPolicy::Accessory); let _ = self.set_activation_policy(tauri::ActivationPolicy::Accessory);
} }
} }

View File

@@ -14,7 +14,7 @@ use tokio::time::sleep;
impl CoreManager { impl CoreManager {
pub async fn use_default_config(&self, error_key: &str, error_msg: &str) -> Result<()> { pub async fn use_default_config(&self, error_key: &str, error_msg: &str) -> Result<()> {
use crate::constants::files::RUNTIME_CONFIG; use crate::constants::files::RUNTIME_CONFIG;
let runtime_path = dirs::app_home_dir()?.join(RUNTIME_CONFIG); let runtime_path = dirs::app_home_dir()?.join(RUNTIME_CONFIG);
let clash_config = Config::clash().await.latest_ref().0.clone(); let clash_config = Config::clash().await.latest_ref().0.clone();
@@ -23,7 +23,7 @@ impl CoreManager {
exists_keys: vec![], exists_keys: vec![],
chain_logs: Default::default(), chain_logs: Default::default(),
}); });
help::save_yaml(&runtime_path, &clash_config, Some("# Clash Verge Runtime")).await?; help::save_yaml(&runtime_path, &clash_config, Some("# Clash Verge Runtime")).await?;
handle::Handle::notice_message(error_key, error_msg); handle::Handle::notice_message(error_key, error_msg);
Ok(()) Ok(())
@@ -38,7 +38,9 @@ impl CoreManager {
return Ok((true, String::new())); return Ok((true, String::new()));
} }
let _permit = self.update_semaphore.try_acquire() let _permit = self
.update_semaphore
.try_acquire()
.map_err(|_| anyhow!("Config update already in progress"))?; .map_err(|_| anyhow!("Config update already in progress"))?;
self.perform_config_update().await self.perform_config_update().await
@@ -47,13 +49,13 @@ impl CoreManager {
fn should_update_config(&self) -> Result<bool> { fn should_update_config(&self) -> Result<bool> {
let now = Instant::now(); let now = Instant::now();
let mut last = self.last_update.lock(); let mut last = self.last_update.lock();
if let Some(last_time) = *last { if let Some(last_time) = *last {
if now.duration_since(last_time) < timing::CONFIG_UPDATE_DEBOUNCE { if now.duration_since(last_time) < timing::CONFIG_UPDATE_DEBOUNCE {
return Ok(false); return Ok(false);
} }
} }
*last = Some(now); *last = Some(now);
Ok(true) Ok(true)
} }
@@ -84,7 +86,7 @@ impl CoreManager {
pub(super) async fn apply_config(&self, path: PathBuf) -> Result<()> { pub(super) async fn apply_config(&self, path: PathBuf) -> Result<()> {
let path_str = dirs::path_to_str(&path)?; let path_str = dirs::path_to_str(&path)?;
match self.reload_config(path_str).await { match self.reload_config(path_str).await {
Ok(_) => { Ok(_) => {
Config::runtime().await.apply(); Config::runtime().await.apply();
@@ -117,7 +119,10 @@ impl CoreManager {
} }
async fn reload_config(&self, path: &str) -> Result<(), MihomoError> { async fn reload_config(&self, path: &str) -> Result<(), MihomoError> {
handle::Handle::mihomo().await.reload_config(true, path).await handle::Handle::mihomo()
.await
.reload_config(true, path)
.await
} }
fn should_restart_on_error(err: &MihomoError) -> bool { fn should_restart_on_error(err: &MihomoError) -> bool {
@@ -125,7 +130,7 @@ impl CoreManager {
MihomoError::ConnectionFailed | MihomoError::ConnectionLost => true, MihomoError::ConnectionFailed | MihomoError::ConnectionLost => true,
MihomoError::Io(io_err) => Self::is_connection_io_error(io_err.kind()), MihomoError::Io(io_err) => Self::is_connection_io_error(io_err.kind()),
MihomoError::Reqwest(req_err) => { MihomoError::Reqwest(req_err) => {
req_err.is_connect() req_err.is_connect()
|| req_err.is_timeout() || req_err.is_timeout()
|| Self::contains_error_pattern(&req_err.to_string()) || Self::contains_error_pattern(&req_err.to_string())
} }
@@ -149,4 +154,3 @@ impl CoreManager {
CONNECTION_ERRORS.iter().any(|p| text.contains(p)) CONNECTION_ERRORS.iter().any(|p| text.contains(p))
} }
} }

View File

@@ -1,6 +1,9 @@
use super::{CoreManager, RunningMode}; use super::{CoreManager, RunningMode};
use crate::{ use crate::{
core::{logger::ClashLogger, service::{ServiceStatus, SERVICE_MANAGER}}, core::{
logger::ClashLogger,
service::{SERVICE_MANAGER, ServiceStatus},
},
logging, logging,
utils::logging::Type, utils::logging::Type,
}; };
@@ -18,7 +21,7 @@ impl CoreManager {
pub async fn stop_core(&self) -> Result<()> { pub async fn stop_core(&self) -> Result<()> {
ClashLogger::global().clear_logs(); ClashLogger::global().clear_logs();
match self.get_running_mode() { match self.get_running_mode() {
RunningMode::Service => self.stop_core_by_service().await, RunningMode::Service => self.stop_core_by_service().await,
RunningMode::Sidecar => self.stop_core_by_sidecar(), RunningMode::Sidecar => self.stop_core_by_sidecar(),
@@ -29,18 +32,19 @@ impl CoreManager {
pub async fn restart_core(&self) -> Result<()> { pub async fn restart_core(&self) -> Result<()> {
logging!(info, Type::Core, "Restarting core"); logging!(info, Type::Core, "Restarting core");
self.stop_core().await?; self.stop_core().await?;
if SERVICE_MANAGER.lock().await.init().await.is_ok() { if SERVICE_MANAGER.lock().await.init().await.is_ok() {
let _ = SERVICE_MANAGER.lock().await.refresh().await; let _ = SERVICE_MANAGER.lock().await.refresh().await;
} }
self.start_core().await self.start_core().await
} }
pub async fn change_core(&self, clash_core: Option<String>) -> Result<(), String> { pub async fn change_core(&self, clash_core: Option<String>) -> Result<(), String> {
use crate::config::{Config, ConfigType, IVerge}; use crate::config::{Config, ConfigType, IVerge};
let core = clash_core.as_ref() let core = clash_core
.as_ref()
.ok_or_else(|| "Clash core cannot be None".to_string())?; .ok_or_else(|| "Clash core cannot be None".to_string())?;
if !IVerge::VALID_CLASH_CORES.contains(&core.as_str()) { if !IVerge::VALID_CLASH_CORES.contains(&core.as_str()) {
@@ -53,7 +57,8 @@ impl CoreManager {
let verge_data = Config::verge().await.latest_ref().clone(); let verge_data = Config::verge().await.latest_ref().clone();
verge_data.save_file().await.map_err(|e| e.to_string())?; verge_data.save_file().await.map_err(|e| e.to_string())?;
let run_path = Config::generate_file(ConfigType::Run).await let run_path = Config::generate_file(ConfigType::Run)
.await
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
self.apply_config(run_path).await.map_err(|e| e.to_string()) self.apply_config(run_path).await.map_err(|e| e.to_string())
@@ -66,7 +71,7 @@ impl CoreManager {
ServiceStatus::Ready => RunningMode::Service, ServiceStatus::Ready => RunningMode::Service,
_ => RunningMode::Sidecar, _ => RunningMode::Sidecar,
}; };
self.set_running_mode(mode); self.set_running_mode(mode);
Ok(()) Ok(())
} }
@@ -76,7 +81,8 @@ impl CoreManager {
use crate::{config::Config, constants::timing}; use crate::{config::Config, constants::timing};
use backoff::{Error as BackoffError, ExponentialBackoff}; use backoff::{Error as BackoffError, ExponentialBackoff};
let needs_service = Config::verge().await let needs_service = Config::verge()
.await
.latest_ref() .latest_ref()
.enable_tun_mode .enable_tun_mode
.unwrap_or(false); .unwrap_or(false);
@@ -107,7 +113,9 @@ impl CoreManager {
if matches!(manager.current(), ServiceStatus::Ready) { if matches!(manager.current(), ServiceStatus::Ready) {
Ok(()) Ok(())
} else { } else {
Err(BackoffError::transient(anyhow::anyhow!("Service not ready"))) Err(BackoffError::transient(anyhow::anyhow!(
"Service not ready"
)))
} }
}; };
@@ -117,4 +125,3 @@ impl CoreManager {
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
async fn wait_for_service_if_needed(&self) {} async fn wait_for_service_if_needed(&self) {}
} }

View File

@@ -68,7 +68,7 @@ impl CoreManager {
pub fn set_running_mode(&self, mode: RunningMode) { pub fn set_running_mode(&self, mode: RunningMode) {
self.state.lock().running_mode = mode; self.state.lock().running_mode = mode;
} }
pub async fn init(&self) -> Result<()> { pub async fn init(&self) -> Result<()> {
self.cleanup_orphaned_processes().await?; self.cleanup_orphaned_processes().await?;
self.start_core().await?; self.start_core().await?;
@@ -77,4 +77,3 @@ impl CoreManager {
} }
singleton_lazy!(CoreManager, CORE_MANAGER, CoreManager::default); singleton_lazy!(CoreManager, CORE_MANAGER, CoreManager::default);

View File

@@ -11,7 +11,12 @@ impl CoreManager {
pub async fn cleanup_orphaned_processes(&self) -> Result<()> { pub async fn cleanup_orphaned_processes(&self) -> Result<()> {
logging!(info, Type::Core, "Cleaning orphaned mihomo processes"); logging!(info, Type::Core, "Cleaning orphaned mihomo processes");
let current_pid = self.state.lock().child_sidecar.as_ref().and_then(|c| c.pid()); let current_pid = self
.state
.lock()
.child_sidecar
.as_ref()
.and_then(|c| c.pid());
let target_processes = process::process_names(); let target_processes = process::process_names();
let process_futures = target_processes.iter().map(|&name| { let process_futures = target_processes.iter().map(|&name| {
@@ -46,19 +51,31 @@ impl CoreManager {
.count(); .count();
if killed_count > 0 { if killed_count > 0 {
logging!(info, Type::Core, "Cleaned {} orphaned processes", killed_count); logging!(
info,
Type::Core,
"Cleaned {} orphaned processes",
killed_count
);
} }
Ok(()) Ok(())
} }
async fn find_processes_by_name(&self, process_name: String, _target: &str) -> Result<(Vec<u32>, String)> { async fn find_processes_by_name(
&self,
process_name: String,
_target: &str,
) -> Result<(Vec<u32>, String)> {
#[cfg(windows)] #[cfg(windows)]
{ {
use std::mem; use std::mem;
use winapi::um::{ use winapi::um::{
handleapi::CloseHandle, handleapi::CloseHandle,
tlhelp32::{CreateToolhelp32Snapshot, PROCESSENTRY32W, Process32FirstW, Process32NextW, TH32CS_SNAPPROCESS}, tlhelp32::{
CreateToolhelp32Snapshot, PROCESSENTRY32W, Process32FirstW, Process32NextW,
TH32CS_SNAPPROCESS,
},
}; };
let process_name_clone = process_name.clone(); let process_name_clone = process_name.clone();
@@ -76,7 +93,10 @@ impl CoreManager {
if Process32FirstW(snapshot, &mut pe32) != 0 { if Process32FirstW(snapshot, &mut pe32) != 0 {
loop { loop {
let end_pos = pe32.szExeFile.iter().position(|&x| x == 0) let end_pos = pe32
.szExeFile
.iter()
.position(|&x| x == 0)
.unwrap_or(pe32.szExeFile.len()); .unwrap_or(pe32.szExeFile.len());
if end_pos > 0 { if end_pos > 0 {
@@ -96,14 +116,19 @@ impl CoreManager {
} }
Ok(pids) Ok(pids)
}).await??; })
.await??;
Ok((pids, process_name)) Ok((pids, process_name))
} }
#[cfg(not(windows))] #[cfg(not(windows))]
{ {
let cmd = if cfg!(target_os = "macos") { "pgrep" } else { "pidof" }; let cmd = if cfg!(target_os = "macos") {
"pgrep"
} else {
"pidof"
};
let output = tokio::process::Command::new(cmd) let output = tokio::process::Command::new(cmd)
.arg(&process_name) .arg(&process_name)
.output() .output()
@@ -140,7 +165,9 @@ impl CoreManager {
let result = TerminateProcess(handle, 1) != 0; let result = TerminateProcess(handle, 1) != 0;
CloseHandle(handle); CloseHandle(handle);
result result
}).await.unwrap_or(false) })
.await
.unwrap_or(false)
}; };
#[cfg(not(windows))] #[cfg(not(windows))]
@@ -158,10 +185,22 @@ impl CoreManager {
tokio::time::sleep(timing::PROCESS_VERIFY_DELAY).await; tokio::time::sleep(timing::PROCESS_VERIFY_DELAY).await;
if self.is_process_running(pid).await.unwrap_or(false) { if self.is_process_running(pid).await.unwrap_or(false) {
logging!(warn, Type::Core, "Process {} (PID: {}) still running after termination", process_name, pid); logging!(
warn,
Type::Core,
"Process {} (PID: {}) still running after termination",
process_name,
pid
);
false false
} else { } else {
logging!(info, Type::Core, "Terminated process {} (PID: {})", process_name, pid); logging!(
info,
Type::Core,
"Terminated process {} (PID: {})",
process_name,
pid
);
true true
} }
} }
@@ -187,7 +226,8 @@ impl CoreManager {
let result = GetExitCodeProcess(handle, &mut exit_code); let result = GetExitCodeProcess(handle, &mut exit_code);
CloseHandle(handle); CloseHandle(handle);
Ok(result != 0 && exit_code == 259) Ok(result != 0 && exit_code == 259)
}).await? })
.await?
} }
#[cfg(not(windows))] #[cfg(not(windows))]
@@ -201,4 +241,3 @@ impl CoreManager {
} }
} }
} }

View File

@@ -2,11 +2,7 @@ use super::{CoreManager, RunningMode};
use crate::{ use crate::{
AsyncHandler, AsyncHandler,
config::Config, config::Config,
core::{ core::{handle, logger::ClashLogger, service},
handle,
logger::ClashLogger,
service,
},
logging, logging,
process::CommandChildGuard, process::CommandChildGuard,
utils::{ utils::{
@@ -59,7 +55,8 @@ impl CoreManager {
state.running_mode = RunningMode::Sidecar; state.running_mode = RunningMode::Sidecar;
} }
let shared_writer: SharedWriter = std::sync::Arc::new(tokio::sync::Mutex::new(sidecar_writer().await?)); let shared_writer: SharedWriter =
std::sync::Arc::new(tokio::sync::Mutex::new(sidecar_writer().await?));
AsyncHandler::spawn(|| async move { AsyncHandler::spawn(|| async move {
while let Some(event) = rx.recv().await { while let Some(event) = rx.recv().await {
@@ -122,4 +119,3 @@ impl CoreManager {
Ok(()) Ok(())
} }
} }

View File

@@ -13,8 +13,4 @@ pub mod tray;
pub mod validate; pub mod validate;
pub mod win_uwp; pub mod win_uwp;
pub use self::{ pub use self::{event_driven_proxy::EventDrivenProxyManager, manager::CoreManager, timer::Timer};
event_driven_proxy::EventDrivenProxyManager,
manager::CoreManager,
timer::Timer,
};

View File

@@ -80,15 +80,20 @@ impl NotificationSystem {
match result { match result {
Ok(handle) => self.worker_handle = Some(handle), Ok(handle) => self.worker_handle = Some(handle),
Err(e) => logging!(error, Type::System, "Failed to start notification worker: {}", e), Err(e) => logging!(
error,
Type::System,
"Failed to start notification worker: {}",
e
),
} }
} }
fn worker_loop(rx: mpsc::Receiver<FrontendEvent>) { fn worker_loop(rx: mpsc::Receiver<FrontendEvent>) {
use super::handle::Handle; use super::handle::Handle;
let handle = Handle::global(); let handle = Handle::global();
while !handle.is_exiting() { while !handle.is_exiting() {
match rx.recv_timeout(std::time::Duration::from_millis(100)) { match rx.recv_timeout(std::time::Duration::from_millis(100)) {
Ok(event) => Self::process_event(&handle, event), Ok(event) => Self::process_event(&handle, event),
@@ -124,7 +129,7 @@ impl NotificationSystem {
fn emit_to_window(&self, window: &WebviewWindow, event: FrontendEvent) { fn emit_to_window(&self, window: &WebviewWindow, event: FrontendEvent) {
let (event_name, payload) = self.serialize_event(event); let (event_name, payload) = self.serialize_event(event);
let Ok(payload) = payload else { let Ok(payload) = payload else {
self.stats.total_errors.fetch_add(1, Ordering::Relaxed); self.stats.total_errors.fetch_add(1, Ordering::Relaxed);
return; return;
@@ -141,15 +146,19 @@ impl NotificationSystem {
} }
} }
fn serialize_event(&self, event: FrontendEvent) -> (&'static str, Result<serde_json::Value, serde_json::Error>) { fn serialize_event(
&self,
event: FrontendEvent,
) -> (&'static str, Result<serde_json::Value, serde_json::Error>) {
use serde_json::json; use serde_json::json;
match event { match event {
FrontendEvent::RefreshClash => ("verge://refresh-clash-config", Ok(json!("yes"))), FrontendEvent::RefreshClash => ("verge://refresh-clash-config", Ok(json!("yes"))),
FrontendEvent::RefreshVerge => ("verge://refresh-verge-config", Ok(json!("yes"))), FrontendEvent::RefreshVerge => ("verge://refresh-verge-config", Ok(json!("yes"))),
FrontendEvent::NoticeMessage { status, message } => { FrontendEvent::NoticeMessage { status, message } => (
("verge://notice-message", serde_json::to_value((status, message))) "verge://notice-message",
} serde_json::to_value((status, message)),
),
FrontendEvent::ProfileChanged { current_profile_id } => { FrontendEvent::ProfileChanged { current_profile_id } => {
("profile-changed", Ok(json!(current_profile_id))) ("profile-changed", Ok(json!(current_profile_id)))
} }
@@ -171,7 +180,12 @@ impl NotificationSystem {
let errors = self.stats.total_errors.load(Ordering::Relaxed); let errors = self.stats.total_errors.load(Ordering::Relaxed);
if errors > retry::EVENT_EMIT_THRESHOLD && !*self.emergency_mode.read() { if errors > retry::EVENT_EMIT_THRESHOLD && !*self.emergency_mode.read() {
logging!(warn, Type::Frontend, "Entering emergency mode after {} errors", errors); logging!(
warn,
Type::Frontend,
"Entering emergency mode after {} errors",
errors
);
*self.emergency_mode.write() = true; *self.emergency_mode.write() = true;
} }
} }
@@ -190,7 +204,7 @@ impl NotificationSystem {
pub fn shutdown(&mut self) { pub fn shutdown(&mut self) {
self.is_running = false; self.is_running = false;
if let Some(sender) = self.sender.take() { if let Some(sender) = self.sender.take() {
drop(sender); drop(sender);
} }
@@ -200,4 +214,3 @@ impl NotificationSystem {
} }
} }
} }