mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
perf: optimize profile handle memory usage
This commit is contained in:
@@ -284,10 +284,10 @@ async fn validate_new_profile(new_profile: &String) -> Result<(), ()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 执行配置更新并处理结果
|
/// 执行配置更新并处理结果
|
||||||
async fn restore_previous_profile(prev_profile: String) -> CmdResult<()> {
|
async fn restore_previous_profile(prev_profile: &String) -> CmdResult<()> {
|
||||||
logging!(info, Type::Cmd, "尝试恢复到之前的配置: {}", prev_profile);
|
logging!(info, Type::Cmd, "尝试恢复到之前的配置: {}", prev_profile);
|
||||||
let restore_profiles = IProfiles {
|
let restore_profiles = IProfiles {
|
||||||
current: Some(prev_profile),
|
current: Some(prev_profile.to_owned()),
|
||||||
items: None,
|
items: None,
|
||||||
};
|
};
|
||||||
Config::profiles()
|
Config::profiles()
|
||||||
@@ -304,7 +304,7 @@ async fn restore_previous_profile(prev_profile: String) -> CmdResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_success(current_value: Option<String>) -> CmdResult<bool> {
|
async fn handle_success(current_value: Option<&String>) -> CmdResult<bool> {
|
||||||
Config::profiles().await.apply();
|
Config::profiles().await.apply();
|
||||||
handle::Handle::refresh_clash();
|
handle::Handle::refresh_clash();
|
||||||
|
|
||||||
@@ -320,9 +320,9 @@ async fn handle_success(current_value: Option<String>) -> CmdResult<bool> {
|
|||||||
logging!(warn, Type::Cmd, "Warning: 异步保存配置文件失败: {e}");
|
logging!(warn, Type::Cmd, "Warning: 异步保存配置文件失败: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(current) = ¤t_value {
|
if let Some(current) = current_value {
|
||||||
logging!(info, Type::Cmd, "向前端发送配置变更事件: {}", current,);
|
logging!(info, Type::Cmd, "向前端发送配置变更事件: {}", current);
|
||||||
handle::Handle::notify_profile_changed(current.clone());
|
handle::Handle::notify_profile_changed(current.to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
@@ -330,7 +330,7 @@ async fn handle_success(current_value: Option<String>) -> CmdResult<bool> {
|
|||||||
|
|
||||||
async fn handle_validation_failure(
|
async fn handle_validation_failure(
|
||||||
error_msg: String,
|
error_msg: String,
|
||||||
current_profile: Option<String>,
|
current_profile: Option<&String>,
|
||||||
) -> CmdResult<bool> {
|
) -> CmdResult<bool> {
|
||||||
logging!(warn, Type::Cmd, "配置验证失败: {}", error_msg);
|
logging!(warn, Type::Cmd, "配置验证失败: {}", error_msg);
|
||||||
Config::profiles().await.discard();
|
Config::profiles().await.discard();
|
||||||
@@ -348,7 +348,7 @@ async fn handle_update_error<E: std::fmt::Display>(e: E) -> CmdResult<bool> {
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_timeout(current_profile: Option<String>) -> CmdResult<bool> {
|
async fn handle_timeout(current_profile: Option<&String>) -> CmdResult<bool> {
|
||||||
let timeout_msg = "配置更新超时(30秒),可能是配置验证或核心通信阻塞";
|
let timeout_msg = "配置更新超时(30秒),可能是配置验证或核心通信阻塞";
|
||||||
logging!(error, Type::Cmd, "{}", timeout_msg);
|
logging!(error, Type::Cmd, "{}", timeout_msg);
|
||||||
Config::profiles().await.discard();
|
Config::profiles().await.discard();
|
||||||
@@ -360,8 +360,8 @@ async fn handle_timeout(current_profile: Option<String>) -> CmdResult<bool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn perform_config_update(
|
async fn perform_config_update(
|
||||||
current_value: Option<String>,
|
current_value: Option<&String>,
|
||||||
current_profile: Option<String>,
|
current_profile: Option<&String>,
|
||||||
) -> CmdResult<bool> {
|
) -> CmdResult<bool> {
|
||||||
let update_result = tokio::time::timeout(
|
let update_result = tokio::time::timeout(
|
||||||
Duration::from_secs(30),
|
Duration::from_secs(30),
|
||||||
@@ -391,7 +391,8 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
|||||||
defer! {
|
defer! {
|
||||||
CURRENT_SWITCHING_PROFILE.store(false, Ordering::Release);
|
CURRENT_SWITCHING_PROFILE.store(false, Ordering::Release);
|
||||||
}
|
}
|
||||||
let target_profile = profiles.current.clone();
|
|
||||||
|
let target_profile = profiles.current.as_ref();
|
||||||
|
|
||||||
logging!(
|
logging!(
|
||||||
info,
|
info,
|
||||||
@@ -401,24 +402,21 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 保存当前配置,以便在验证失败时恢复
|
// 保存当前配置,以便在验证失败时恢复
|
||||||
let current_profile = Config::profiles().await.latest_arc().current.clone();
|
let previous_profile = Config::profiles().await.data_arc().current.clone();
|
||||||
logging!(info, Type::Cmd, "当前配置: {:?}", current_profile);
|
logging!(info, Type::Cmd, "当前配置: {:?}", previous_profile);
|
||||||
|
|
||||||
// 如果要切换配置,先检查目标配置文件是否有语法错误
|
// 如果要切换配置,先检查目标配置文件是否有语法错误
|
||||||
if let Some(new_profile) = profiles.current.as_ref()
|
if let Some(switch_to_profile) = target_profile
|
||||||
&& current_profile.as_ref() != Some(new_profile)
|
&& previous_profile.as_ref() != Some(switch_to_profile)
|
||||||
&& validate_new_profile(new_profile).await.is_err()
|
&& validate_new_profile(switch_to_profile).await.is_err()
|
||||||
{
|
{
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = Config::profiles()
|
let _ = Config::profiles()
|
||||||
.await
|
.await
|
||||||
.edit_draft(|d| d.patch_config(&profiles));
|
.edit_draft(|d| d.patch_config(&profiles));
|
||||||
|
|
||||||
let current_value = profiles.current.clone();
|
perform_config_update(target_profile, previous_profile.as_ref()).await
|
||||||
|
|
||||||
perform_config_update(current_value, current_profile).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 根据profile name修改profiles
|
/// 根据profile name修改profiles
|
||||||
|
|||||||
@@ -50,28 +50,26 @@ impl IProfiles {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn new() -> Self {
|
pub async fn new() -> Self {
|
||||||
match dirs::profiles_path() {
|
let path = match dirs::profiles_path() {
|
||||||
Ok(path) => match help::read_yaml::<Self>(&path).await {
|
Ok(p) => p,
|
||||||
Ok(mut profiles) => {
|
Err(err) => {
|
||||||
if profiles.items.is_none() {
|
logging!(error, Type::Config, "{err}");
|
||||||
profiles.items = Some(vec![]);
|
return Self::default();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match help::read_yaml::<Self>(&path).await {
|
||||||
|
Ok(mut profiles) => {
|
||||||
|
let items = profiles.items.get_or_insert_with(Vec::new);
|
||||||
|
for item in items.iter_mut() {
|
||||||
|
if item.uid.is_none() {
|
||||||
|
item.uid = Some(help::get_uid("d").into());
|
||||||
}
|
}
|
||||||
// compatible with the old old old version
|
|
||||||
if let Some(items) = profiles.items.as_mut() {
|
|
||||||
for item in items.iter_mut() {
|
|
||||||
if item.uid.is_none() {
|
|
||||||
item.uid = Some(help::get_uid("d").into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
profiles
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
profiles
|
||||||
logging!(error, Type::Config, "{err}");
|
}
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
logging!(error, Type::Config, "{err}");
|
logging!(error, Type::Config, "{err}");
|
||||||
Self::default()
|
Self::default()
|
||||||
@@ -433,12 +431,12 @@ impl IProfiles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 获取所有的profiles(uid,名称)
|
/// 获取所有的profiles(uid,名称)
|
||||||
pub fn all_profile_uid_and_name(&self) -> Option<Vec<(String, String)>> {
|
pub fn all_profile_uid_and_name(&self) -> Option<Vec<(&String, &String)>> {
|
||||||
self.items.as_ref().map(|items| {
|
self.items.as_ref().map(|items| {
|
||||||
items
|
items
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
if let (Some(uid), Some(name)) = (e.uid.clone(), e.name.clone()) {
|
if let (Some(uid), Some(name)) = (e.uid.as_ref(), e.name.as_ref()) {
|
||||||
Some((uid, name))
|
Some((uid, name))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -318,11 +318,9 @@ impl Tray {
|
|||||||
.unwrap_or("rule")
|
.unwrap_or("rule")
|
||||||
.to_owned()
|
.to_owned()
|
||||||
};
|
};
|
||||||
let profile_uid_and_name = Config::profiles()
|
let profiles_config = Config::profiles().await;
|
||||||
.await
|
let profiles_arc = profiles_config.latest_arc();
|
||||||
.latest_arc()
|
let profile_uid_and_name = profiles_arc.all_profile_uid_and_name().unwrap_or_default();
|
||||||
.all_profile_uid_and_name()
|
|
||||||
.unwrap_or_default();
|
|
||||||
let is_lightweight_mode = is_in_lightweight_mode();
|
let is_lightweight_mode = is_in_lightweight_mode();
|
||||||
|
|
||||||
match app_handle.tray_by_id("main") {
|
match app_handle.tray_by_id("main") {
|
||||||
@@ -666,7 +664,7 @@ fn create_hotkeys(hotkeys: &Option<Vec<String>>) -> HashMap<String, String> {
|
|||||||
|
|
||||||
async fn create_profile_menu_item(
|
async fn create_profile_menu_item(
|
||||||
app_handle: &AppHandle,
|
app_handle: &AppHandle,
|
||||||
profile_uid_and_name: Vec<(String, String)>,
|
profile_uid_and_name: Vec<(&String, &String)>,
|
||||||
) -> Result<Vec<CheckMenuItem<Wry>>> {
|
) -> Result<Vec<CheckMenuItem<Wry>>> {
|
||||||
let futures = profile_uid_and_name
|
let futures = profile_uid_and_name
|
||||||
.iter()
|
.iter()
|
||||||
@@ -870,7 +868,7 @@ async fn create_tray_menu(
|
|||||||
system_proxy_enabled: bool,
|
system_proxy_enabled: bool,
|
||||||
tun_mode_enabled: bool,
|
tun_mode_enabled: bool,
|
||||||
tun_mode_available: bool,
|
tun_mode_available: bool,
|
||||||
profile_uid_and_name: Vec<(String, String)>,
|
profile_uid_and_name: Vec<(&String, &String)>,
|
||||||
is_lightweight_mode: bool,
|
is_lightweight_mode: bool,
|
||||||
) -> Result<tauri::menu::Menu<Wry>> {
|
) -> Result<tauri::menu::Menu<Wry>> {
|
||||||
let current_proxy_mode = mode.unwrap_or("");
|
let current_proxy_mode = mode.unwrap_or("");
|
||||||
|
|||||||
Reference in New Issue
Block a user