diff --git a/Changelog.md b/Changelog.md index fe9fccf2b..ebf4a97f2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ - 修复无网络时无限请求 IP 归属查询 - 修复 WebDAV 页面重试逻辑 - 修复 Linux 通过 GUI 安装服务模式权限不符合预期 +- 修复切换订阅所导致的内存持续增长
✨ 新增功能 diff --git a/src-tauri/src/config/config.rs b/src-tauri/src/config/config.rs index 7b1d986d7..376e98e85 100644 --- a/src-tauri/src/config/config.rs +++ b/src-tauri/src/config/config.rs @@ -189,6 +189,10 @@ impl Config { pub async fn generate() -> Result<()> { let (config, exists_keys, logs) = enhance::enhance().await; + Self::runtime().await.edit_draft(|d| { + d.clean_all(); + }); + Self::runtime().await.edit_draft(|d| { *d = IRuntime { config: Some(config), diff --git a/src-tauri/src/config/runtime.rs b/src-tauri/src/config/runtime.rs index 25c8fe767..dc72aa566 100644 --- a/src-tauri/src/config/runtime.rs +++ b/src-tauri/src/config/runtime.rs @@ -22,6 +22,13 @@ impl IRuntime { Self::default() } + #[inline] + pub fn clean_all(&mut self) { + self.config = None; + self.exists_keys.clear(); + self.chain_logs.clear(); + } + // 这里只更改 allow-lan | ipv6 | log-level | tun #[inline] pub fn patch_config(&mut self, patch: &Mapping) { diff --git a/src-tauri/src/enhance/mod.rs b/src-tauri/src/enhance/mod.rs index f74981ff0..45cdaeec4 100644 --- a/src-tauri/src/enhance/mod.rs +++ b/src-tauri/src/enhance/mod.rs @@ -13,6 +13,7 @@ use self::{ seq::{SeqMap, use_seq}, tun::use_tun, }; +use crate::process::AsyncHandler; use crate::utils::dirs; use crate::{config::Config, utils::tmpl}; use crate::{config::IVerge, constants}; @@ -33,6 +34,7 @@ struct ConfigValues { socks_enabled: bool, http_enabled: bool, enable_dns_settings: bool, + enable_external_controller: bool, #[cfg(not(target_os = "windows"))] redir_enabled: bool, #[cfg(target_os = "linux")] @@ -108,13 +110,22 @@ async fn get_config_values() -> ConfigValues { .. } = *verge_arc; - let (clash_core, enable_tun, enable_builtin, socks_enabled, http_enabled, enable_dns_settings) = ( + let ( + clash_core, + enable_tun, + enable_builtin, + socks_enabled, + http_enabled, + enable_dns_settings, + enable_external_controller, + ) = ( Some(verge_arc.get_valid_clash_core()), enable_tun_mode.unwrap_or(false), enable_builtin_enhanced.unwrap_or(true), verge_socks_enabled.unwrap_or(false), verge_http_enabled.unwrap_or(false), enable_dns_settings.unwrap_or(false), + verge_arc.enable_external_controller.unwrap_or(false), ); #[cfg(not(target_os = "windows"))] @@ -134,6 +145,7 @@ async fn get_config_values() -> ConfigValues { socks_enabled, http_enabled, enable_dns_settings, + enable_external_controller, #[cfg(not(target_os = "windows"))] redir_enabled, #[cfg(target_os = "linux")] @@ -378,11 +390,12 @@ fn process_profile_items( (config, exists_keys, result_map) } -async fn merge_default_config( +fn merge_default_config( mut config: Mapping, clash_config: Mapping, socks_enabled: bool, http_enabled: bool, + enable_external_controller: bool, #[cfg(not(target_os = "windows"))] redir_enabled: bool, #[cfg(target_os = "linux")] tproxy_enabled: bool, ) -> Mapping { @@ -433,19 +446,8 @@ async fn merge_default_config( } } // 处理 external-controller 键的开关逻辑 - if key.as_str() == Some("external-controller") { - let enable_external_controller = Config::verge() - .await - .latest_arc() - .enable_external_controller - .unwrap_or(false); - - if enable_external_controller { - config.insert(key, value); - } else { - // 如果禁用了外部控制器,设置为空字符串 - config.insert(key, "".into()); - } + if key.as_str() == Some("external-controller") && !enable_external_controller { + config.insert(key, "".into()); } else { config.insert(key, value); } @@ -602,6 +604,7 @@ pub async fn enhance() -> (Mapping, HashSet, HashMap) socks_enabled, http_enabled, enable_dns_settings, + enable_external_controller, #[cfg(not(target_os = "windows"))] redir_enabled, #[cfg(target_os = "linux")] @@ -620,48 +623,58 @@ pub async fn enhance() -> (Mapping, HashSet, HashMap) let global_script = profile.global_script; let profile_name = profile.profile_name; - // process globals - let (config, exists_keys, result_map) = process_global_items(config, global_merge, global_script, &profile_name); + let (config, exists_keys_set, result_map) = AsyncHandler::spawn_blocking(move || { + // process globals + let (config, exists_keys, result_map) = + process_global_items(config, global_merge, global_script, &profile_name); - // process profile-specific items - let (config, exists_keys, result_map) = process_profile_items( - config, - exists_keys, - result_map, - rules_item, - proxies_item, - groups_item, - merge_item, - script_item, - &profile_name, - ); + // process profile-specific items + let (config, exists_keys, result_map) = process_profile_items( + config, + exists_keys, + result_map, + rules_item, + proxies_item, + groups_item, + merge_item, + script_item, + &profile_name, + ); - // merge default clash config - let config = merge_default_config( - config, - clash_config, - socks_enabled, - http_enabled, - #[cfg(not(target_os = "windows"))] - redir_enabled, - #[cfg(target_os = "linux")] - tproxy_enabled, - ) - .await; + // merge default clash config + let config = merge_default_config( + config, + clash_config, + socks_enabled, + http_enabled, + enable_external_controller, + #[cfg(not(target_os = "windows"))] + redir_enabled, + #[cfg(target_os = "linux")] + tproxy_enabled, + ); - // builtin scripts - let mut config = apply_builtin_scripts(config, clash_core, enable_builtin); + // builtin scripts + let mut config = apply_builtin_scripts(config, clash_core.clone(), enable_builtin); - config = cleanup_proxy_groups(config); + config = cleanup_proxy_groups(config); - config = use_tun(config, enable_tun); - config = use_sort(config); + config = use_tun(config, enable_tun); + config = use_sort(config); + + let mut exists_keys_set = HashSet::new(); + exists_keys_set.extend(exists_keys); + + (config, exists_keys_set, result_map) + }) + .await + .unwrap_or_else(|e| { + logging!(error, Type::Core, "enhance task join error: {}", e); + (Mapping::new(), HashSet::new(), HashMap::new()) + }); // dns settings - config = apply_dns_settings(config, enable_dns_settings).await; - - let mut exists_keys_set = HashSet::new(); - exists_keys_set.extend(exists_keys); + let config = apply_dns_settings(config, enable_dns_settings).await; (config, exists_keys_set, result_map) }