refactor: streamline error handling and resource management in various modules
This commit is contained in:
@@ -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"
|
||||
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"
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,18 +56,17 @@ fn get_tray_click_debounce() -> &'static Mutex<Instant> {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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, "计时器已取消");
|
||||
|
||||
@@ -43,18 +43,20 @@ impl<T: Clone> Draft<T> {
|
||||
{
|
||||
// 先获得写锁以创建或取出草稿 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<Box<T>>)
|
||||
#[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>(要求 T: Clone)
|
||||
let boxed = Arc::make_mut(arc_box); // &mut Box<T>
|
||||
let boxed = Arc::make_mut(&mut draft_arc); // &mut Box<T>
|
||||
// 对 Box<T> 解引用得到 &mut T
|
||||
|
||||
f(&mut **boxed)
|
||||
let result = f(&mut **boxed);
|
||||
// 恢复修改后的草稿 Arc
|
||||
self.inner.write().1 = Some(draft_arc);
|
||||
result
|
||||
}
|
||||
|
||||
/// 将草稿提交到已提交位置(替换),并清除草稿
|
||||
@@ -90,8 +92,7 @@ impl<T: Clone> Draft<T> {
|
||||
let (new_local, res) = f(local).await?;
|
||||
|
||||
// 将新的 Box<T> 放到已提交位置(包进 Arc)
|
||||
let mut guard = self.inner.write();
|
||||
guard.0 = Arc::new(new_local);
|
||||
self.inner.write().0 = Arc::new(new_local);
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -54,9 +54,7 @@ fn get_ui_ready_notify() -> &'static Arc<Notify> {
|
||||
// 更新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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user