feat: implement CmdProxyState for managing proxy refresh state and add state management module

refactor: remove unnecessary macOS conditional compilation directive
This commit is contained in:
Tunglies
2025-06-05 13:43:02 +08:00
Unverified
parent 7c738483b7
commit fee6a586d7
6 changed files with 49 additions and 47 deletions

View File

@@ -1,15 +1,12 @@
use super::CmdResult;
use crate::module::mihomo::MihomoManager;
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use crate::{core::handle, module::mihomo::MihomoManager, state::proxy::CmdProxyState};
use std::{
sync::atomic::{AtomicBool, Ordering},
sync::Mutex,
time::{Duration, Instant},
};
use tauri::Manager;
static LAST_REFRESH_TIME: Lazy<Mutex<Option<Instant>>> = Lazy::new(|| Mutex::new(None));
static IS_REFRESHING: AtomicBool = AtomicBool::new(false);
const REFRESH_INTERVAL: Duration = Duration::from_secs(5);
const PROVIDERS_REFRESH_INTERVAL: Duration = Duration::from_secs(3);
#[tauri::command]
pub async fn get_proxies() -> CmdResult<serde_json::Value> {
@@ -24,48 +21,35 @@ pub async fn get_proxies() -> CmdResult<serde_json::Value> {
#[tauri::command]
pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
let manager = MihomoManager::global();
let cached_data = manager.get_providers_proxies();
let app_handle = handle::Handle::global().app_handle().unwrap();
let cmd_proxy_state = app_handle.state::<Mutex<CmdProxyState>>();
let safe_data = if cached_data.is_null() {
serde_json::json!({
"providers": {}
})
} else {
cached_data
};
// 检查是否需要刷新
let should_refresh = {
let last_refresh = LAST_REFRESH_TIME.lock();
match *last_refresh {
Some(last_time) => last_time.elapsed() > REFRESH_INTERVAL,
None => true,
let mut state = cmd_proxy_state.lock().unwrap();
let now = Instant::now();
if now.duration_since(state.last_refresh_time) > PROVIDERS_REFRESH_INTERVAL {
state.need_refresh = true;
state.last_refresh_time = now;
}
state.need_refresh
};
if should_refresh && !IS_REFRESHING.load(Ordering::Acquire) {
IS_REFRESHING.store(true, Ordering::Release);
if should_refresh {
let manager = MihomoManager::global();
if let Err(e) = manager.refresh_providers_proxies().await {
log::warn!(target: "app", "providers_proxies刷新失败: {}", e);
return Err(e.into());
}
crate::process::AsyncHandler::spawn(|| async move {
let manager = MihomoManager::global();
match manager.refresh_providers_proxies().await {
Ok(_) => {
log::debug!(target: "app", "providers_proxies静默后台刷新成功");
}
Err(e) => {
log::warn!(target: "app", "providers_proxies后台刷新失败: {}", e);
}
}
{
let mut last_refresh = LAST_REFRESH_TIME.lock();
*last_refresh = Some(Instant::now());
}
IS_REFRESHING.store(false, Ordering::Release);
});
let mut state = cmd_proxy_state.lock().unwrap();
state.providers_proxies = manager.get_providers_proxies().clone();
state.need_refresh = false;
log::debug!(target: "app", "providers_proxies刷新成功");
}
Ok(safe_data)
let providers_proxies = {
let state = cmd_proxy_state.lock().unwrap();
state.providers_proxies.clone()
};
Ok(providers_proxies)
}

View File

@@ -1 +0,0 @@
pub mod service;

View File

@@ -1 +0,0 @@

View File

@@ -2,10 +2,10 @@ mod cmd;
mod config;
mod core;
mod enhance;
mod error;
mod feat;
mod module;
mod process;
mod state;
mod utils;
use crate::{
core::hotkey,
@@ -15,7 +15,6 @@ use crate::{
use config::Config;
use std::sync::{Mutex, Once};
use tauri::AppHandle;
#[cfg(target_os = "macos")]
use tauri::Manager;
use tauri_plugin_autostart::MacosLauncher;
use tauri_plugin_deep_link::DeepLinkExt;
@@ -205,6 +204,8 @@ pub fn run() {
logging!(error, Type::Setup, true, "初始化资源失败: {}", e);
}
app.manage(Mutex::new(state::proxy::CmdProxyState::default()));
logging!(info, Type::Setup, true, "初始化完成,继续执行");
Ok(())
})

View File

@@ -0,0 +1,4 @@
// Tauri Manager 会进行 Arc 管理,无需额外 Arc
// https://tauri.app/develop/state-management/#do-you-need-arc
pub mod proxy;

View File

@@ -0,0 +1,15 @@
pub struct CmdProxyState {
pub last_refresh_time: std::time::Instant,
pub need_refresh: bool,
pub providers_proxies: serde_json::Value,
}
impl Default for CmdProxyState {
fn default() -> Self {
Self {
last_refresh_time: std::time::Instant::now(),
need_refresh: true,
providers_proxies: serde_json::Value::Null,
}
}
}