refactor(proxy): enhance proxy state management and refresh logic
This commit is contained in:
@@ -7,16 +7,40 @@ use std::{
|
|||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
|
|
||||||
const PROVIDERS_REFRESH_INTERVAL: Duration = Duration::from_secs(3);
|
const PROVIDERS_REFRESH_INTERVAL: Duration = Duration::from_secs(3);
|
||||||
|
const PROXIES_REFRESH_INTERVAL: Duration = Duration::from_secs(1);
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_proxies() -> CmdResult<serde_json::Value> {
|
pub async fn get_proxies() -> CmdResult<serde_json::Value> {
|
||||||
let manager = MihomoManager::global();
|
let manager = MihomoManager::global();
|
||||||
|
|
||||||
manager
|
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||||
.refresh_proxies()
|
let cmd_proxy_state = app_handle.state::<Mutex<CmdProxyState>>();
|
||||||
.await
|
|
||||||
.map(|_| manager.get_proxies())
|
let should_refresh = {
|
||||||
.or_else(|_| Ok(manager.get_proxies()))
|
let mut state = cmd_proxy_state.lock().unwrap();
|
||||||
|
let now = Instant::now();
|
||||||
|
if now.duration_since(state.last_refresh_time) > PROXIES_REFRESH_INTERVAL {
|
||||||
|
state.need_refresh = true;
|
||||||
|
state.last_refresh_time = now;
|
||||||
|
}
|
||||||
|
state.need_refresh
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_refresh {
|
||||||
|
let proxies = manager.get_refresh_proxies().await?;
|
||||||
|
{
|
||||||
|
let mut state = cmd_proxy_state.lock().unwrap();
|
||||||
|
state.proxies = proxies;
|
||||||
|
state.need_refresh = false;
|
||||||
|
}
|
||||||
|
log::debug!(target: "app", "proxies刷新成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
let proxies = {
|
||||||
|
let state = cmd_proxy_state.lock().unwrap();
|
||||||
|
state.proxies.clone()
|
||||||
|
};
|
||||||
|
Ok(proxies)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -36,14 +60,12 @@ pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
|
|||||||
|
|
||||||
if should_refresh {
|
if should_refresh {
|
||||||
let manager = MihomoManager::global();
|
let manager = MihomoManager::global();
|
||||||
if let Err(e) = manager.refresh_providers_proxies().await {
|
let providers = manager.get_providers_proxies().await?;
|
||||||
log::warn!(target: "app", "providers_proxies刷新失败: {}", e);
|
{
|
||||||
return Err(e.into());
|
let mut state = cmd_proxy_state.lock().unwrap();
|
||||||
|
state.providers_proxies = providers;
|
||||||
|
state.need_refresh = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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刷新成功");
|
log::debug!(target: "app", "providers_proxies刷新成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
pub struct CmdProxyState {
|
pub struct CmdProxyState {
|
||||||
pub last_refresh_time: std::time::Instant,
|
pub last_refresh_time: std::time::Instant,
|
||||||
pub need_refresh: bool,
|
pub need_refresh: bool,
|
||||||
|
pub proxies: serde_json::Value,
|
||||||
pub providers_proxies: serde_json::Value,
|
pub providers_proxies: serde_json::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ impl Default for CmdProxyState {
|
|||||||
Self {
|
Self {
|
||||||
last_refresh_time: std::time::Instant::now(),
|
last_refresh_time: std::time::Instant::now(),
|
||||||
need_refresh: true,
|
need_refresh: true,
|
||||||
|
proxies: serde_json::Value::Null,
|
||||||
providers_proxies: serde_json::Value::Null,
|
providers_proxies: serde_json::Value::Null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
use reqwest::{Method, header::HeaderMap};
|
use reqwest::{Method, header::HeaderMap};
|
||||||
use serde_json::json;
|
use serde_json::{Value, json};
|
||||||
use std::{
|
use std::time::Duration;
|
||||||
sync::{Arc, Mutex},
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub use model::{MihomoData, MihomoManager};
|
pub use model::MihomoManager;
|
||||||
|
|
||||||
impl MihomoManager {
|
impl MihomoManager {
|
||||||
pub fn new(mihomo_server: String, headers: HeaderMap) -> Self {
|
pub fn new(mihomo_server: String, headers: HeaderMap) -> Self {
|
||||||
@@ -20,38 +17,10 @@ impl MihomoManager {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
mihomo_server,
|
mihomo_server,
|
||||||
data: Arc::new(Mutex::new(MihomoData {
|
|
||||||
proxies: serde_json::Value::Null,
|
|
||||||
providers_proxies: serde_json::Value::Null,
|
|
||||||
})),
|
|
||||||
client,
|
client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_proxies(&self, proxies: serde_json::Value) {
|
|
||||||
let mut data = self.data.lock().expect("Mutex poisoned");
|
|
||||||
data.proxies = proxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_providers_proxies(&self, providers_proxies: serde_json::Value) {
|
|
||||||
let mut data = self.data.lock().expect("Mutex poisoned");
|
|
||||||
data.providers_proxies = providers_proxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mihomo_server(&self) -> String {
|
|
||||||
self.mihomo_server.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_proxies(&self) -> serde_json::Value {
|
|
||||||
let data = self.data.lock().expect("Mutex poisoned");
|
|
||||||
data.proxies.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_providers_proxies(&self) -> serde_json::Value {
|
|
||||||
let data = self.data.lock().expect("Mutex poisoned");
|
|
||||||
data.providers_proxies.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_request(
|
async fn send_request(
|
||||||
&self,
|
&self,
|
||||||
method: Method,
|
method: Method,
|
||||||
@@ -87,18 +56,16 @@ impl MihomoManager {
|
|||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn refresh_proxies(&self) -> Result<&Self, String> {
|
pub async fn get_refresh_proxies(&self) -> Result<Value, String> {
|
||||||
let url = format!("{}/proxies", self.mihomo_server);
|
let url = format!("{}/proxies", self.mihomo_server);
|
||||||
let proxies = self.send_request(Method::GET, url, None).await?;
|
let proxies = self.send_request(Method::GET, url, None).await?;
|
||||||
self.update_proxies(proxies);
|
Ok(proxies)
|
||||||
Ok(self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn refresh_providers_proxies(&self) -> Result<&Self, String> {
|
pub async fn get_providers_proxies(&self) -> Result<Value, String> {
|
||||||
let url = format!("{}/providers/proxies", self.mihomo_server);
|
let url = format!("{}/providers/proxies", self.mihomo_server);
|
||||||
let providers_proxies = self.send_request(Method::GET, url, None).await?;
|
let providers_proxies = self.send_request(Method::GET, url, None).await?;
|
||||||
self.update_providers_proxies(providers_proxies);
|
Ok(providers_proxies)
|
||||||
Ok(self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn close_all_connections(&self) -> Result<(), String> {
|
pub async fn close_all_connections(&self) -> Result<(), String> {
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
pub struct MihomoData {
|
|
||||||
pub(crate) proxies: serde_json::Value,
|
|
||||||
pub(crate) providers_proxies: serde_json::Value,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MihomoManager {
|
pub struct MihomoManager {
|
||||||
pub(crate) mihomo_server: String,
|
pub(crate) mihomo_server: String,
|
||||||
pub(crate) data: Arc<Mutex<MihomoData>>,
|
|
||||||
pub(crate) client: reqwest::Client,
|
pub(crate) client: reqwest::Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,7 @@
|
|||||||
use mihomo_api;
|
|
||||||
use reqwest::header::HeaderMap;
|
use reqwest::header::HeaderMap;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mihomo_manager_init() {
|
fn test_mihomo_manager_init() {
|
||||||
let manager = mihomo_api::MihomoManager::new("url".into(), HeaderMap::new());
|
let _ = mihomo_api::MihomoManager::new("url".into(), HeaderMap::new());
|
||||||
assert_eq!(manager.get_proxies(), serde_json::Value::Null);
|
assert_eq!(true, true);
|
||||||
assert_eq!(manager.get_providers_proxies(), serde_json::Value::Null);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_refresh_proxies() {
|
|
||||||
let manager = mihomo_api::MihomoManager::new("http://127.0.0.1:9097".into(), HeaderMap::new());
|
|
||||||
let manager = manager.refresh_proxies().await.unwrap();
|
|
||||||
let proxies = manager.get_proxies();
|
|
||||||
let providers = manager.get_providers_proxies();
|
|
||||||
assert_ne!(proxies, serde_json::Value::Null);
|
|
||||||
assert_eq!(providers, serde_json::Value::Null);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_refresh_providers_proxies() {
|
|
||||||
let manager = mihomo_api::MihomoManager::new("http://127.0.0.1:9097".into(), HeaderMap::new());
|
|
||||||
let manager = manager.refresh_providers_proxies().await.unwrap();
|
|
||||||
let proxies = manager.get_proxies();
|
|
||||||
let providers = manager.get_providers_proxies();
|
|
||||||
assert_eq!(proxies, serde_json::Value::Null);
|
|
||||||
assert_ne!(providers, serde_json::Value::Null);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user