fix: service unexpected status after restart app in unix (#5768)

* fix: 修复macos重启应用后需要重设服务器模式问题

* chore: remove package-lock.json (using pnpm)

* Delete test.sh

* refactor(lifecycle): remove unnecessary conditional compilation for macOS and Windows

* refactor(timing): remove conditional compilation for service wait durations on Windows and macOS

---------

Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
hank
2025-12-11 20:09:27 +08:00
committed by GitHub
parent 2aaa91f4cb
commit 2995f61087
2 changed files with 36 additions and 12 deletions

View File

@@ -1,5 +1,3 @@
use std::time::Duration;
pub mod network {
pub const DEFAULT_EXTERNAL_CONTROLLER: &str = "127.0.0.1:9097";
@@ -20,16 +18,14 @@ pub mod network {
}
pub mod timing {
use super::Duration;
use std::time::Duration;
pub const CONFIG_UPDATE_DEBOUNCE: Duration = Duration::from_millis(300);
pub const EVENT_EMIT_DELAY: Duration = Duration::from_millis(20);
pub const STARTUP_ERROR_DELAY: Duration = Duration::from_secs(2);
pub const ERROR_BATCH_DELAY: Duration = Duration::from_millis(300);
#[cfg(target_os = "windows")]
pub const SERVICE_WAIT_MAX: Duration = Duration::from_millis(3000);
#[cfg(target_os = "windows")]
pub const SERVICE_WAIT_INTERVAL: Duration = Duration::from_millis(200);
}

View File

@@ -1,10 +1,12 @@
use super::{CoreManager, RunningMode};
use crate::cmd::StringifyErr as _;
use crate::config::{Config, IVerge};
use crate::constants::timing;
use crate::core::handle::Handle;
use crate::core::manager::CLASH_LOGGER;
use crate::core::service::{SERVICE_MANAGER, ServiceStatus};
use anyhow::Result;
use backoff::{Error as BackoffError, ExponentialBackoff};
use clash_verge_logging::{Type, logging};
use scopeguard::defer;
use smartstring::alias::String;
@@ -63,7 +65,6 @@ impl CoreManager {
}
async fn prepare_startup(&self) -> Result<()> {
#[cfg(target_os = "windows")]
self.wait_for_service_if_needed().await;
let value = SERVICE_MANAGER.lock().await.current();
@@ -81,17 +82,40 @@ impl CoreManager {
tauri_plugin_clash_verge_sysinfo::set_app_core_mode(app_handle, self.get_running_mode().to_string());
}
#[cfg(target_os = "windows")]
async fn wait_for_service_if_needed(&self) {
use crate::{config::Config, constants::timing};
use backoff::{Error as BackoffError, ExponentialBackoff};
#[cfg(target_os = "windows")]
{
let needs_service = Config::verge().await.latest_arc().enable_tun_mode.unwrap_or(false);
let needs_service = Config::verge().await.latest_arc().enable_tun_mode.unwrap_or(false);
if !needs_service {
return;
}
}
if !needs_service {
// 在 unix 上,如果服务状态是 "Need Checks",尝试初始化服务管理器
// 在 Windows 上,只有在需要 TUN 模式时才等待服务
let mut manager = SERVICE_MANAGER.lock().await;
let current_status = manager.current();
// 如果服务状态是 "Need Checks",尝试初始化服务管理器
if matches!(current_status, ServiceStatus::Unavailable(ref reason) if reason == "Need Checks") {
// 尝试初始化服务管理器,即使 IPC 路径可能暂时不存在
if let Err(e) = manager.init().await {
logging!(debug, Type::Core, "服务管理器初始化失败(可能服务未启动): {}", e);
} else {
// 初始化成功,尝试刷新状态
let _ = manager.refresh().await;
}
}
// 如果服务已经就绪,直接返回
if matches!(manager.current(), ServiceStatus::Ready) {
return;
}
drop(manager);
// 使用退避重试策略等待服务就绪
let backoff = ExponentialBackoff {
initial_interval: timing::SERVICE_WAIT_INTERVAL,
max_interval: timing::SERVICE_WAIT_INTERVAL,
@@ -108,7 +132,11 @@ impl CoreManager {
return Ok(());
}
manager.init().await.map_err(BackoffError::transient)?;
// 如果服务管理器未初始化,尝试初始化
if matches!(manager.current(), ServiceStatus::Unavailable(ref reason) if reason == "Need Checks") {
manager.init().await.map_err(BackoffError::transient)?;
}
let _ = manager.refresh().await;
if matches!(manager.current(), ServiceStatus::Ready) {