From 69a706b438f01fa78bc5c447f92a896b99ff2f0a Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Thu, 6 Nov 2025 10:18:20 +0800 Subject: [PATCH] refactor: streamline error handling and resource management in various modules --- src-tauri/Cargo.toml | 8 +++++++- src-tauri/src/core/handle.rs | 3 +-- src-tauri/src/core/manager/lifecycle.rs | 3 ++- src-tauri/src/core/manager/state.rs | 16 ++++++++++++---- src-tauri/src/core/notification.rs | 9 ++++++--- src-tauri/src/core/timer.rs | 19 +++++++++---------- src-tauri/src/core/tray/mod.rs | 7 +++---- src-tauri/src/feat/clash.rs | 1 + src-tauri/src/module/lightweight.rs | 13 ++++++++----- src-tauri/src/utils/draft.rs | 25 +++++++++++++------------ src-tauri/src/utils/network.rs | 7 ++----- src-tauri/src/utils/resolve/ui.rs | 4 +--- src-tauri/src/utils/window_manager.rs | 1 + 13 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 7540f675..51b5811e 100755 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -227,4 +227,10 @@ needless_raw_string_hashes = "deny" # Too many in existing code or_fun_call = "deny" cognitive_complexity = "deny" useless_let_if_seq = "deny" -use_self = "deny" \ No newline at end of file +use_self = "deny" +tuple_array_conversions = "deny" +trait_duplication_in_bounds = "deny" +suspicious_operation_groupings = "deny" +string_lit_as_bytes = "deny" +significant_drop_tightening = "deny" +significant_drop_in_scrutinee = "deny" \ No newline at end of file diff --git a/src-tauri/src/core/handle.rs b/src-tauri/src/core/handle.rs index 69eefb2f..52d700e9 100644 --- a/src-tauri/src/core/handle.rs +++ b/src-tauri/src/core/handle.rs @@ -109,8 +109,7 @@ impl Handle { let msg_str = msg.into(); if !*handle.startup_completed.read() { - let mut errors = handle.startup_errors.write(); - errors.push(ErrorMessage { + handle.startup_errors.write().push(ErrorMessage { status: status_str, message: msg_str, }); diff --git a/src-tauri/src/core/manager/lifecycle.rs b/src-tauri/src/core/manager/lifecycle.rs index c299c1ef..75574068 100644 --- a/src-tauri/src/core/manager/lifecycle.rs +++ b/src-tauri/src/core/manager/lifecycle.rs @@ -68,7 +68,8 @@ impl CoreManager { #[cfg(target_os = "windows")] self.wait_for_service_if_needed().await; - let mode = match SERVICE_MANAGER.lock().await.current() { + let value = SERVICE_MANAGER.lock().await.current(); + let mode = match value { ServiceStatus::Ready => RunningMode::Service, _ => RunningMode::Sidecar, }; diff --git a/src-tauri/src/core/manager/state.rs b/src-tauri/src/core/manager/state.rs index f13bc543..2be3be1b 100644 --- a/src-tauri/src/core/manager/state.rs +++ b/src-tauri/src/core/manager/state.rs @@ -62,8 +62,12 @@ impl CoreManager { | tauri_plugin_shell::process::CommandEvent::Stderr(line) => { let mut now = DeferredNow::default(); let message = CompactString::from(String::from_utf8_lossy(&line).as_ref()); - let w = shared_writer.lock().await; - write_sidecar_log(w, &mut now, Level::Error, &message); + write_sidecar_log( + shared_writer.lock().await, + &mut now, + Level::Error, + &message, + ); CLASH_LOGGER.append_log(message).await; } tauri_plugin_shell::process::CommandEvent::Terminated(term) => { @@ -75,8 +79,12 @@ impl CoreManager { } else { CompactString::from("Process terminated") }; - let w = shared_writer.lock().await; - write_sidecar_log(w, &mut now, Level::Info, &message); + write_sidecar_log( + shared_writer.lock().await, + &mut now, + Level::Info, + &message, + ); CLASH_LOGGER.clear_logs().await; break; } diff --git a/src-tauri/src/core/notification.rs b/src-tauri/src/core/notification.rs index 50968bec..2d5d2003 100644 --- a/src-tauri/src/core/notification.rs +++ b/src-tauri/src/core/notification.rs @@ -102,10 +102,13 @@ impl NotificationSystem { } } + // Clippy 似乎对 parking lot 的 RwLock 有误报,这里禁用相关警告 + #[allow(clippy::significant_drop_tightening)] fn process_event(handle: &super::handle::Handle, event: FrontendEvent) { - let system_guard = handle.notification_system.read(); - let Some(system) = system_guard.as_ref() else { - return; + let binding = handle.notification_system.read(); + let system = match binding.as_ref() { + Some(s) => s, + None => return, }; if system.should_skip_event(&event) { diff --git a/src-tauri/src/core/timer.rs b/src-tauri/src/core/timer.rs index 46bd9af3..59699ab1 100644 --- a/src-tauri/src/core/timer.rs +++ b/src-tauri/src/core/timer.rs @@ -154,7 +154,6 @@ impl Timer { /// 每 3 秒更新系统托盘菜单,总共执行 3 次 pub fn add_update_tray_menu_task(&self) -> Result<()> { let tid = self.timer_count.fetch_add(1, Ordering::SeqCst); - let delay_timer = self.delay_timer.write(); let task = TaskBuilder::default() .set_task_id(tid) .set_maximum_parallel_runnable_num(1) @@ -164,7 +163,8 @@ impl Timer { crate::core::tray::Tray::global().update_menu().await }) .context("failed to create update tray menu timer task")?; - delay_timer + self.delay_timer + .write() .add_task(task) .context("failed to add update tray menu timer task")?; Ok(()) @@ -193,14 +193,12 @@ impl Timer { // Perform sync operations while holding locks { - let mut timer_map = self.timer_map.write(); - let delay_timer = self.delay_timer.write(); - for (uid, diff) in diff_map { match diff { DiffFlag::Del(tid) => { - timer_map.remove(&uid); - if let Err(e) = delay_timer.remove_task(tid) { + self.timer_map.write().remove(&uid); + let value = self.delay_timer.write().remove_task(tid); + if let Err(e) = value { logging!( warn, Type::Timer, @@ -220,12 +218,13 @@ impl Timer { last_run: chrono::Local::now().timestamp(), }; - timer_map.insert(uid.clone(), task); + self.timer_map.write().insert(uid.clone(), task); operations_to_add.push((uid, tid, interval)); } DiffFlag::Mod(tid, interval) => { // Remove old task first - if let Err(e) = delay_timer.remove_task(tid) { + let value = self.delay_timer.write().remove_task(tid); + if let Err(e) = value { logging!( warn, Type::Timer, @@ -243,7 +242,7 @@ impl Timer { last_run: chrono::Local::now().timestamp(), }; - timer_map.insert(uid.clone(), task); + self.timer_map.write().insert(uid.clone(), task); operations_to_add.push((uid, tid, interval)); } } diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index 81fc4160..e19491f3 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -56,18 +56,17 @@ fn get_tray_click_debounce() -> &'static Mutex { fn should_handle_tray_click() -> bool { let debounce_lock = get_tray_click_debounce(); - let mut last_click = debounce_lock.lock(); let now = Instant::now(); - if now.duration_since(*last_click) >= Duration::from_millis(TRAY_CLICK_DEBOUNCE_MS) { - *last_click = now; + if now.duration_since(*debounce_lock.lock()) >= Duration::from_millis(TRAY_CLICK_DEBOUNCE_MS) { + *debounce_lock.lock() = now; true } else { logging!( debug, Type::Tray, "托盘点击被防抖机制忽略,距离上次点击 {}ms", - now.duration_since(*last_click).as_millis() + now.duration_since(*debounce_lock.lock()).as_millis() ); false } diff --git a/src-tauri/src/feat/clash.rs b/src-tauri/src/feat/clash.rs index 6551d440..5fe26b2b 100644 --- a/src-tauri/src/feat/clash.rs +++ b/src-tauri/src/feat/clash.rs @@ -47,6 +47,7 @@ fn after_change_clash_mode() { for connection in connections_array { let _ = mihomo.close_connection(&connection.id).await; } + drop(mihomo); } } Err(err) => { diff --git a/src-tauri/src/module/lightweight.rs b/src-tauri/src/module/lightweight.rs index 3854bbfa..48baeef0 100644 --- a/src-tauri/src/module/lightweight.rs +++ b/src-tauri/src/module/lightweight.rs @@ -268,11 +268,14 @@ async fn setup_light_weight_timer() -> Result<()> { } fn cancel_light_weight_timer() -> Result<()> { - let mut timer_map = Timer::global().timer_map.write(); - let delay_timer = Timer::global().delay_timer.write(); - - if let Some(task) = timer_map.remove(LIGHT_WEIGHT_TASK_UID) { - delay_timer + let value = Timer::global() + .timer_map + .write() + .remove(LIGHT_WEIGHT_TASK_UID); + if let Some(task) = value { + Timer::global() + .delay_timer + .write() .remove_task(task.task_id) .context("failed to remove timer task")?; logging!(debug, Type::Timer, "计时器已取消"); diff --git a/src-tauri/src/utils/draft.rs b/src-tauri/src/utils/draft.rs index 52d9119d..cc81b1f2 100644 --- a/src-tauri/src/utils/draft.rs +++ b/src-tauri/src/utils/draft.rs @@ -43,18 +43,20 @@ impl Draft { { // 先获得写锁以创建或取出草稿 Arc 的可变引用位置 let mut guard = self.inner.write(); - if guard.1.is_none() { - // 创建草稿 snapshot(Arc clone,cheap) - guard.1 = Some(Arc::clone(&guard.0)); - } - // 此时 guaranteed: guard.1 is Some(Arc>) - #[allow(clippy::unwrap_used)] - let arc_box = guard.1.as_mut().unwrap(); + let mut draft_arc = if guard.1.is_none() { + Arc::clone(&guard.0) + } else { + #[allow(clippy::unwrap_used)] + guard.1.take().unwrap() + }; + drop(guard); // Arc::make_mut: 如果只有一个引用则返回可变引用;否则会克隆底层 Box(要求 T: Clone) - let boxed = Arc::make_mut(arc_box); // &mut Box + let boxed = Arc::make_mut(&mut draft_arc); // &mut Box // 对 Box 解引用得到 &mut T - - f(&mut **boxed) + let result = f(&mut **boxed); + // 恢复修改后的草稿 Arc + self.inner.write().1 = Some(draft_arc); + result } /// 将草稿提交到已提交位置(替换),并清除草稿 @@ -90,8 +92,7 @@ impl Draft { let (new_local, res) = f(local).await?; // 将新的 Box 放到已提交位置(包进 Arc) - let mut guard = self.inner.write(); - guard.0 = Arc::new(new_local); + self.inner.write().0 = Arc::new(new_local); Ok(res) } diff --git a/src-tauri/src/utils/network.rs b/src-tauri/src/utils/network.rs index d2353673..f9926c48 100644 --- a/src-tauri/src/utils/network.rs +++ b/src-tauri/src/utils/network.rs @@ -80,8 +80,7 @@ impl NetworkManager { } async fn record_connection_error(&self, error: &str) { - let mut last_error = self.last_connection_error.lock().await; - *last_error = Some((Instant::now(), error.into())); + *self.last_connection_error.lock().await = Some((Instant::now(), error.into())); let mut count = self.connection_error_count.lock().await; *count += 1; @@ -89,13 +88,11 @@ impl NetworkManager { async fn should_reset_clients(&self) -> bool { let count = *self.connection_error_count.lock().await; - let last_error_guard = self.last_connection_error.lock().await; - if count > 5 { return true; } - if let Some((time, _)) = &*last_error_guard + if let Some((time, _)) = &*self.last_connection_error.lock().await && time.elapsed() < Duration::from_secs(30) && count > 2 { diff --git a/src-tauri/src/utils/resolve/ui.rs b/src-tauri/src/utils/resolve/ui.rs index 4ebe30ad..55d5d852 100644 --- a/src-tauri/src/utils/resolve/ui.rs +++ b/src-tauri/src/utils/resolve/ui.rs @@ -54,9 +54,7 @@ fn get_ui_ready_notify() -> &'static Arc { // 更新UI准备阶段 pub fn update_ui_ready_stage(stage: UiReadyStage) { let state = get_ui_ready_state(); - let mut stage_lock = state.stage.write(); - - *stage_lock = stage; + *state.stage.write() = stage; // 如果是最终阶段,标记UI完全就绪 if stage == UiReadyStage::Ready { mark_ui_ready(); diff --git a/src-tauri/src/utils/window_manager.rs b/src-tauri/src/utils/window_manager.rs index 2d5b7a1b..801b3894 100644 --- a/src-tauri/src/utils/window_manager.rs +++ b/src-tauri/src/utils/window_manager.rs @@ -81,6 +81,7 @@ fn should_handle_window_operation() -> bool { if elapsed >= Duration::from_millis(WINDOW_OPERATION_DEBOUNCE_MS) { *last_operation = now; + drop(last_operation); WINDOW_OPERATION_IN_PROGRESS.store(true, Ordering::Release); logging!(info, Type::Window, "[防抖] 窗口操作被允许执行"); true