mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:02:22 +08:00
refactor: Replace tokio::spawn with AsyncHandler::spawn for better task management
- Replace direct tokio::spawn calls with AsyncHandler::spawn across multiple modules - Improves task lifecycle management and error handling consistency - Affected files: - src-tauri/src/cmd/network.rs - src-tauri/src/core/core.rs - src-tauri/src/core/event_driven_proxy.rs - src-tauri/src/enhance/tun.rs - src-tauri/src/ipc/logs.rs - src-tauri/src/ipc/memory.rs - src-tauri/src/ipc/monitor.rs - src-tauri/src/ipc/traffic.rs - src-tauri/src/utils/network.rs - src-tauri/src/utils/resolve.rs This change provides better control over async task spawning and helps prevent potential issues with unmanaged background tasks.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use super::CmdResult;
|
use super::CmdResult;
|
||||||
use crate::core::{async_proxy_query::AsyncProxyQuery, EventDrivenProxyManager};
|
use crate::core::{async_proxy_query::AsyncProxyQuery, EventDrivenProxyManager};
|
||||||
|
use crate::process::AsyncHandler;
|
||||||
use crate::wrap_err;
|
use crate::wrap_err;
|
||||||
use network_interface::NetworkInterface;
|
use network_interface::NetworkInterface;
|
||||||
use serde_yaml::Mapping;
|
use serde_yaml::Mapping;
|
||||||
@@ -32,7 +33,7 @@ pub async fn get_auto_proxy() -> CmdResult<Mapping> {
|
|||||||
|
|
||||||
let current = proxy_manager.get_auto_proxy_cached();
|
let current = proxy_manager.get_auto_proxy_cached();
|
||||||
// 异步请求更新,立即返回缓存数据
|
// 异步请求更新,立即返回缓存数据
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
let _ = proxy_manager.get_auto_proxy_async().await;
|
let _ = proxy_manager.get_auto_proxy_async().await;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ use crate::{
|
|||||||
service::{self},
|
service::{self},
|
||||||
},
|
},
|
||||||
ipc::IpcManager,
|
ipc::IpcManager,
|
||||||
logging, logging_error, singleton_lazy,
|
logging, logging_error,
|
||||||
|
process::AsyncHandler,
|
||||||
|
singleton_lazy,
|
||||||
utils::{
|
utils::{
|
||||||
dirs,
|
dirs,
|
||||||
help::{self},
|
help::{self},
|
||||||
@@ -763,7 +765,7 @@ impl CoreManager {
|
|||||||
])
|
])
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
|
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
while let Some(event) = rx.recv().await {
|
while let Some(event) = rx.recv().await {
|
||||||
if let tauri_plugin_shell::process::CommandEvent::Stdout(line) = event {
|
if let tauri_plugin_shell::process::CommandEvent::Stdout(line) = event {
|
||||||
if let Err(e) = writeln!(log_file, "{}", String::from_utf8_lossy(&line)) {
|
if let Err(e) = writeln!(log_file, "{}", String::from_utf8_lossy(&line)) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
|||||||
use crate::config::{Config, IVerge};
|
use crate::config::{Config, IVerge};
|
||||||
use crate::core::async_proxy_query::AsyncProxyQuery;
|
use crate::core::async_proxy_query::AsyncProxyQuery;
|
||||||
use crate::logging_error;
|
use crate::logging_error;
|
||||||
|
use crate::process::AsyncHandler;
|
||||||
use crate::utils::logging::Type;
|
use crate::utils::logging::Type;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use sysproxy::{Autoproxy, Sysproxy};
|
use sysproxy::{Autoproxy, Sysproxy};
|
||||||
@@ -176,7 +177,7 @@ impl EventDrivenProxyManager {
|
|||||||
event_rx: mpsc::UnboundedReceiver<ProxyEvent>,
|
event_rx: mpsc::UnboundedReceiver<ProxyEvent>,
|
||||||
query_rx: mpsc::UnboundedReceiver<QueryRequest>,
|
query_rx: mpsc::UnboundedReceiver<QueryRequest>,
|
||||||
) {
|
) {
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
log::info!(target: "app", "事件驱动代理管理器启动");
|
log::info!(target: "app", "事件驱动代理管理器启动");
|
||||||
|
|
||||||
// 将 mpsc 接收器包装成 Stream,避免每次循环创建 future
|
// 将 mpsc 接收器包装成 Stream,避免每次循环创建 future
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
use serde_yaml::{Mapping, Value};
|
use serde_yaml::{Mapping, Value};
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use crate::process::AsyncHandler;
|
||||||
|
|
||||||
macro_rules! revise {
|
macro_rules! revise {
|
||||||
($map: expr, $key: expr, $val: expr) => {
|
($map: expr, $key: expr, $val: expr) => {
|
||||||
let ret_key = Value::String($key.into());
|
let ret_key = Value::String($key.into());
|
||||||
@@ -59,7 +62,7 @@ pub fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
|
|||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
tokio::spawn(async {
|
AsyncHandler::spawn(move || async move {
|
||||||
crate::utils::resolve::restore_public_dns().await;
|
crate::utils::resolve::restore_public_dns().await;
|
||||||
crate::utils::resolve::set_public_dns("223.6.6.6".to_string()).await;
|
crate::utils::resolve::set_public_dns("223.6.6.6".to_string()).await;
|
||||||
});
|
});
|
||||||
@@ -71,7 +74,7 @@ pub fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
|
|||||||
} else {
|
} else {
|
||||||
// TUN未启用时,仅恢复系统DNS,不修改配置文件中的DNS设置
|
// TUN未启用时,仅恢复系统DNS,不修改配置文件中的DNS设置
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
tokio::spawn(async {
|
AsyncHandler::spawn(move || async move {
|
||||||
crate::utils::resolve::restore_public_dns().await;
|
crate::utils::resolve::restore_public_dns().await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::VecDeque, sync::Arc, time::Instant};
|
use std::{collections::VecDeque, sync::Arc, time::Instant};
|
||||||
use tokio::{sync::RwLock, task::JoinHandle, time::Duration};
|
use tauri::async_runtime::JoinHandle;
|
||||||
|
use tokio::{sync::RwLock, time::Duration};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ipc::monitor::MonitorData,
|
ipc::monitor::MonitorData,
|
||||||
logging, singleton_with_logging,
|
logging,
|
||||||
|
process::AsyncHandler,
|
||||||
|
singleton_with_logging,
|
||||||
utils::{dirs::ipc_path, logging::Type},
|
utils::{dirs::ipc_path, logging::Type},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,7 +162,7 @@ impl LogsMonitor {
|
|||||||
|
|
||||||
let monitor_current = Arc::clone(&self.current);
|
let monitor_current = Arc::clone(&self.current);
|
||||||
|
|
||||||
let task = tokio::spawn(async move {
|
let task = AsyncHandler::spawn(move || async move {
|
||||||
loop {
|
loop {
|
||||||
// Get fresh IPC path and client for each connection attempt
|
// Get fresh IPC path and client for each connection attempt
|
||||||
let (_ipc_path_buf, client) = match Self::create_ipc_client() {
|
let (_ipc_path_buf, client) = match Self::create_ipc_client() {
|
||||||
@@ -256,7 +259,7 @@ impl LogsMonitor {
|
|||||||
// We only need to accept all logs since filtering is done at the endpoint level
|
// We only need to accept all logs since filtering is done at the endpoint level
|
||||||
let log_item = LogItem::new(log_data.log_type, log_data.payload);
|
let log_item = LogItem::new(log_data.log_type, log_data.payload);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
let mut logs = current.write().await;
|
let mut logs = current.write().await;
|
||||||
|
|
||||||
// Add new log
|
// Add new log
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use tokio::{sync::RwLock, time::Duration};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ipc::monitor::{IpcStreamMonitor, MonitorData, StreamingParser},
|
ipc::monitor::{IpcStreamMonitor, MonitorData, StreamingParser},
|
||||||
|
process::AsyncHandler,
|
||||||
singleton_lazy_with_logging,
|
singleton_lazy_with_logging,
|
||||||
utils::format::fmt_bytes,
|
utils::format::fmt_bytes,
|
||||||
};
|
};
|
||||||
@@ -47,7 +48,7 @@ impl StreamingParser for CurrentMemory {
|
|||||||
current: Arc<RwLock<Self>>,
|
current: Arc<RwLock<Self>>,
|
||||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
if let Ok(memory) = serde_json::from_str::<MemoryData>(line.trim()) {
|
if let Ok(memory) = serde_json::from_str::<MemoryData>(line.trim()) {
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
let mut current_guard = current.write().await;
|
let mut current_guard = current.write().await;
|
||||||
current_guard.inuse = memory.inuse;
|
current_guard.inuse = memory.inuse;
|
||||||
current_guard.oslimit = memory.oslimit;
|
current_guard.oslimit = memory.oslimit;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use tokio::{sync::RwLock, time::Duration};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
logging,
|
logging,
|
||||||
|
process::AsyncHandler,
|
||||||
utils::{dirs::ipc_path, logging::Type},
|
utils::{dirs::ipc_path, logging::Type},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ where
|
|||||||
let endpoint_clone = endpoint.clone();
|
let endpoint_clone = endpoint.clone();
|
||||||
|
|
||||||
// Start the monitoring task
|
// Start the monitoring task
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
Self::streaming_task(monitor_current, endpoint_clone, timeout, retry_interval).await;
|
Self::streaming_task(monitor_current, endpoint_clone, timeout, retry_interval).await;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use tokio::{sync::RwLock, time::Duration};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ipc::monitor::{IpcStreamMonitor, MonitorData, StreamingParser},
|
ipc::monitor::{IpcStreamMonitor, MonitorData, StreamingParser},
|
||||||
|
process::AsyncHandler,
|
||||||
singleton_lazy_with_logging,
|
singleton_lazy_with_logging,
|
||||||
utils::format::fmt_bytes,
|
utils::format::fmt_bytes,
|
||||||
};
|
};
|
||||||
@@ -68,7 +69,7 @@ impl StreamingParser for TrafficMonitorState {
|
|||||||
current: Arc<RwLock<Self>>,
|
current: Arc<RwLock<Self>>,
|
||||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
if let Ok(traffic) = serde_json::from_str::<TrafficData>(line.trim()) {
|
if let Ok(traffic) = serde_json::from_str::<TrafficData>(line.trim()) {
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
let mut state_guard = current.write().await;
|
let mut state_guard = current.write().await;
|
||||||
|
|
||||||
let (up_rate, down_rate) = state_guard
|
let (up_rate, down_rate) = state_guard
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tokio::runtime::{Builder, Runtime};
|
use tokio::runtime::{Builder, Runtime};
|
||||||
|
|
||||||
use crate::{config::Config, logging, singleton_lazy, utils::logging::Type};
|
use crate::{config::Config, logging, process::AsyncHandler, singleton_lazy, utils::logging::Type};
|
||||||
|
|
||||||
// HTTP2 相关
|
// HTTP2 相关
|
||||||
const H2_CONNECTION_WINDOW_SIZE: u32 = 1024 * 1024;
|
const H2_CONNECTION_WINDOW_SIZE: u32 = 1024 * 1024;
|
||||||
@@ -351,7 +351,7 @@ impl NetworkManager {
|
|||||||
let (cancel_tx, cancel_rx) = tokio::sync::oneshot::channel::<()>();
|
let (cancel_tx, cancel_rx) = tokio::sync::oneshot::channel::<()>();
|
||||||
|
|
||||||
let url_clone = url.to_string();
|
let url_clone = url.to_string();
|
||||||
let watchdog = tokio::spawn(async move {
|
let watchdog = AsyncHandler::spawn(move || async move {
|
||||||
tokio::time::sleep(Duration::from_secs(timeout_duration)).await;
|
tokio::time::sleep(Duration::from_secs(timeout_duration)).await;
|
||||||
let _ = cancel_tx.send(());
|
let _ = cancel_tx.send(());
|
||||||
logging!(warn, Type::Network, true, "请求超时取消: {}", url_clone);
|
logging!(warn, Type::Network, true, "请求超时取消: {}", url_clone);
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ pub fn create_window(is_show: bool) -> bool {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 异步监控UI状态,使用try_read避免死锁
|
// 异步监控UI状态,使用try_read避免死锁
|
||||||
tokio::spawn(async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
logging!(
|
logging!(
|
||||||
debug,
|
debug,
|
||||||
Type::Window,
|
Type::Window,
|
||||||
|
|||||||
Reference in New Issue
Block a user