From 3eb2a5b3efa32b06607b2d75d834a52d1fcf0af7 Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Fri, 1 Aug 2025 23:02:11 +0800 Subject: [PATCH] refactor: optimize timer and network management with atomic operations --- src-tauri/src/core/timer.rs | 51 +++++++++++++++-------------- src-tauri/src/enhance/script.rs | 9 +++-- src-tauri/src/lib.rs | 1 + src-tauri/src/module/lightweight.rs | 7 ++-- src-tauri/src/utils/network.rs | 35 ++++++++++---------- src-tauri/src/utils/resolve.rs | 17 ++++------ 6 files changed, 58 insertions(+), 62 deletions(-) diff --git a/src-tauri/src/core/timer.rs b/src-tauri/src/core/timer.rs index 668a23e0..27d7d116 100644 --- a/src-tauri/src/core/timer.rs +++ b/src-tauri/src/core/timer.rs @@ -1,9 +1,14 @@ -use crate::{config::Config, feat, logging, logging_error, utils::logging::Type}; +use crate::{config::Config, feat, logging, logging_error, singleton, utils::logging::Type}; use anyhow::{Context, Result}; use delay_timer::prelude::{DelayTimer, DelayTimerBuilder, TaskBuilder}; -use once_cell::sync::OnceCell; -use parking_lot::{Mutex, RwLock}; -use std::{collections::HashMap, sync::Arc}; +use parking_lot::RwLock; +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicBool, AtomicU64, Ordering}, + Arc, + }, +}; type TaskID = u64; @@ -22,23 +27,24 @@ pub struct Timer { /// save the current state - using RwLock for better read concurrency pub timer_map: Arc>>, - /// increment id - kept as mutex since it's just a counter - pub timer_count: Arc>, + /// increment id - atomic counter for better performance + pub timer_count: AtomicU64, /// Flag to mark if timer is initialized - atomic for better performance - pub initialized: Arc, + pub initialized: AtomicBool, } -impl Timer { - pub fn global() -> &'static Timer { - static TIMER: OnceCell = OnceCell::new(); +// Use singleton macro +singleton!(Timer, TIMER_INSTANCE); - TIMER.get_or_init(|| Timer { +impl Timer { + fn new() -> Self { + Timer { delay_timer: Arc::new(RwLock::new(DelayTimerBuilder::default().build())), timer_map: Arc::new(RwLock::new(HashMap::new())), - timer_count: Arc::new(Mutex::new(1)), - initialized: Arc::new(std::sync::atomic::AtomicBool::new(false)), - }) + timer_count: AtomicU64::new(1), + initialized: AtomicBool::new(false), + } } /// Initialize timer with better error handling and atomic operations @@ -46,12 +52,7 @@ impl Timer { // Use compare_exchange for thread-safe initialization check if self .initialized - .compare_exchange( - false, - true, - std::sync::atomic::Ordering::SeqCst, - std::sync::atomic::Ordering::SeqCst, - ) + .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) .is_err() { logging!(debug, Type::Timer, "Timer already initialized, skipping..."); @@ -63,8 +64,7 @@ impl Timer { // Initialize timer tasks if let Err(e) = self.refresh() { // Reset initialization flag on error - self.initialized - .store(false, std::sync::atomic::Ordering::SeqCst); + self.initialized.store(false, Ordering::SeqCst); logging_error!(Type::Timer, false, "Failed to initialize timer: {}", e); return Err(e); } @@ -299,7 +299,8 @@ impl Timer { } // Find new tasks to add - let mut next_id = *self.timer_count.lock(); + let mut next_id = self.timer_count.load(Ordering::Relaxed); + let original_id = next_id; for (uid, &interval) in new_map.iter() { if !timer_map.contains_key(uid) { @@ -316,8 +317,8 @@ impl Timer { } // Update counter only if we added new tasks - if next_id > *self.timer_count.lock() { - *self.timer_count.lock() = next_id; + if next_id > original_id { + self.timer_count.store(next_id, Ordering::Relaxed); } logging!(debug, Type::Timer, "定时任务变更数量: {}", diff_map.len()); diff --git a/src-tauri/src/enhance/script.rs b/src-tauri/src/enhance/script.rs index b36a9214..11a89728 100644 --- a/src-tauri/src/enhance/script.rs +++ b/src-tauri/src/enhance/script.rs @@ -8,11 +8,10 @@ pub fn use_script( name: String, ) -> Result<(Mapping, Vec<(String, String)>)> { use boa_engine::{native_function::NativeFunction, Context, JsValue, Source}; - use parking_lot::Mutex; - use std::sync::Arc; + use std::{cell::RefCell, rc::Rc}; let mut context = Context::default(); - let outputs = Arc::new(Mutex::new(vec![])); + let outputs = Rc::new(RefCell::new(vec![])); let copy_outputs = outputs.clone(); unsafe { @@ -25,7 +24,7 @@ pub fn use_script( let level = level.to_std_string().unwrap(); let data = args.get(1).unwrap().to_string(context)?; let data = data.to_std_string().unwrap(); - let mut out = copy_outputs.lock(); + let mut out = copy_outputs.borrow_mut(); out.push((level, data)); Ok(JsValue::undefined()) }, @@ -68,7 +67,7 @@ pub fn use_script( // 直接解析JSON结果,不做其他解析 let res: Result = parse_json_safely(&result); - let mut out = outputs.lock(); + let mut out = outputs.borrow_mut(); match res { Ok(config) => Ok((use_lowercase(config), out.to_vec())), Err(err) => { diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e3d95b5c..513c825f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -162,6 +162,7 @@ mod app_init { /// Setup plugins for the Tauri builder pub fn setup_plugins(builder: tauri::Builder) -> tauri::Builder { + #[allow(unused_mut)] let mut builder = builder .plugin(tauri_plugin_notification::init()) .plugin(tauri_plugin_updater::Builder::new().build()) diff --git a/src-tauri/src/module/lightweight.rs b/src-tauri/src/module/lightweight.rs index 00c159d8..98d5ba97 100644 --- a/src-tauri/src/module/lightweight.rs +++ b/src-tauri/src/module/lightweight.rs @@ -254,10 +254,9 @@ fn setup_light_weight_timer() -> Result<()> { // 获取task_id let task_id = { - let mut timer_count = Timer::global().timer_count.lock(); - let id = *timer_count; - *timer_count += 1; - id + Timer::global() + .timer_count + .fetch_add(1, std::sync::atomic::Ordering::Relaxed) }; // 创建任务 diff --git a/src-tauri/src/utils/network.rs b/src-tauri/src/utils/network.rs index dfa5fcef..6532a5d0 100644 --- a/src-tauri/src/utils/network.rs +++ b/src-tauri/src/utils/network.rs @@ -2,7 +2,10 @@ use anyhow::Result; use parking_lot::Mutex; use reqwest::{Client, ClientBuilder, Proxy, RequestBuilder, Response}; use std::{ - sync::{Arc, Once}, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, Once, + }, time::{Duration, Instant}, }; use tokio::runtime::{Builder, Runtime}; @@ -23,12 +26,12 @@ const POOL_IDLE_TIMEOUT: Duration = Duration::from_secs(15); /// 网络管理器 pub struct NetworkManager { runtime: Arc, - self_proxy_client: Arc>>, - system_proxy_client: Arc>>, - no_proxy_client: Arc>>, + self_proxy_client: Mutex>, + system_proxy_client: Mutex>, + no_proxy_client: Mutex>, init: Once, - last_connection_error: Arc>>, - connection_error_count: Arc>, + last_connection_error: Mutex>, + connection_error_count: AtomicUsize, } // Use singleton_lazy macro to replace lazy_static! @@ -47,12 +50,12 @@ impl NetworkManager { NetworkManager { runtime: Arc::new(runtime), - self_proxy_client: Arc::new(Mutex::new(None)), - system_proxy_client: Arc::new(Mutex::new(None)), - no_proxy_client: Arc::new(Mutex::new(None)), + self_proxy_client: Mutex::new(None), + system_proxy_client: Mutex::new(None), + no_proxy_client: Mutex::new(None), init: Once::new(), - last_connection_error: Arc::new(Mutex::new(None)), - connection_error_count: Arc::new(Mutex::new(0)), + last_connection_error: Mutex::new(None), + connection_error_count: AtomicUsize::new(0), } } @@ -85,12 +88,11 @@ impl NetworkManager { let mut last_error = self.last_connection_error.lock(); *last_error = Some((Instant::now(), error.to_string())); - let mut error_count = self.connection_error_count.lock(); - *error_count += 1; + self.connection_error_count.fetch_add(1, Ordering::Relaxed); } fn should_reset_clients(&self) -> bool { - let error_count = *self.connection_error_count.lock(); + let error_count = self.connection_error_count.load(Ordering::Relaxed); let last_error = self.last_connection_error.lock(); if error_count > 5 { @@ -120,10 +122,7 @@ impl NetworkManager { let mut client = self.no_proxy_client.lock(); *client = None; } - { - let mut error_count = self.connection_error_count.lock(); - *error_count = 0; - } + self.connection_error_count.store(0, Ordering::Relaxed); } /// 创建带有自定义选项的HTTP请求 diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index 10a33c28..cdbd7877 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/src-tauri/src/utils/resolve.rs @@ -15,10 +15,7 @@ use parking_lot::{Mutex, RwLock}; use percent_encoding::percent_decode_str; use scopeguard; use serde_yaml::Mapping; -use std::{ - sync::Arc, - time::{Duration, Instant}, -}; +use std::time::{Duration, Instant}; use tauri::{AppHandle, Manager}; use tokio::net::TcpListener; @@ -33,7 +30,7 @@ const DEFAULT_WIDTH: u32 = 940; const DEFAULT_HEIGHT: u32 = 700; // 添加全局UI准备就绪标志 -static UI_READY: OnceCell>> = OnceCell::new(); +static UI_READY: OnceCell> = OnceCell::new(); // 窗口创建锁,防止并发创建窗口 static WINDOW_CREATING: OnceCell> = OnceCell::new(); @@ -63,18 +60,18 @@ impl Default for UiReadyState { } // 获取UI就绪状态细节 -static UI_READY_STATE: OnceCell> = OnceCell::new(); +static UI_READY_STATE: OnceCell = OnceCell::new(); fn get_window_creating_lock() -> &'static Mutex<(bool, Instant)> { WINDOW_CREATING.get_or_init(|| Mutex::new((false, Instant::now()))) } -fn get_ui_ready() -> &'static Arc> { - UI_READY.get_or_init(|| Arc::new(RwLock::new(false))) +fn get_ui_ready() -> &'static RwLock { + UI_READY.get_or_init(|| RwLock::new(false)) } -fn get_ui_ready_state() -> &'static Arc { - UI_READY_STATE.get_or_init(|| Arc::new(UiReadyState::default())) +fn get_ui_ready_state() -> &'static UiReadyState { + UI_READY_STATE.get_or_init(UiReadyState::default) } // 更新UI准备阶段