refactor: replace isServiceAvailable with getRunningMode for service status checks

This commit is contained in:
Tunglies
2025-05-26 16:08:16 +08:00
parent 2b89f07fe5
commit 32ee1b36d2
6 changed files with 61 additions and 125 deletions

View File

@@ -2,8 +2,10 @@ use super::CmdResult;
use crate::module::mihomo::MihomoManager; use crate::module::mihomo::MihomoManager;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::sync::atomic::{AtomicBool, Ordering}; use std::{
use std::time::{Duration, Instant}; sync::atomic::{AtomicBool, Ordering},
time::{Duration, Instant},
};
static LAST_REFRESH_TIME: Lazy<Mutex<Option<Instant>>> = Lazy::new(|| Mutex::new(None)); static LAST_REFRESH_TIME: Lazy<Mutex<Option<Instant>>> = Lazy::new(|| Mutex::new(None));
static IS_REFRESHING: AtomicBool = AtomicBool::new(false); static IS_REFRESHING: AtomicBool = AtomicBool::new(false);

View File

@@ -715,8 +715,8 @@ pub async fn check_service_needs_reinstall() -> bool {
logging!(error, Type::Service, true, "检查服务版本失败: {}", err); logging!(error, Type::Service, true, "检查服务版本失败: {}", err);
// 检查服务是否可用 // 检查服务是否可用
match is_service_running().await { match is_service_available().await {
Ok(true) => { Ok(()) => {
log::info!(target: "app", "服务正在运行但版本检查失败: {}", err); log::info!(target: "app", "服务正在运行但版本检查失败: {}", err);
/* logging!( /* logging!(
info, info,
@@ -846,7 +846,7 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
}; };
if version_check { if version_check {
if let Ok(true) = is_service_running().await { if is_service_available().await.is_ok() {
log::info!(target: "app", "服务已在运行且版本匹配,尝试使用"); log::info!(target: "app", "服务已在运行且版本匹配,尝试使用");
return start_with_existing_service(config_file).await; return start_with_existing_service(config_file).await;
} }
@@ -947,14 +947,14 @@ pub(super) async fn stop_core_by_service() -> Result<()> {
} }
/// 检查服务是否正在运行 /// 检查服务是否正在运行
pub async fn is_service_running() -> Result<bool> { pub async fn is_service_available() -> Result<()> {
logging!(info, Type::Service, true, "开始检查服务是否正在运行"); logging!(info, Type::Service, true, "开始检查服务是否正在运行");
match check_ipc_service_status().await { match check_ipc_service_status().await {
Ok(resp) => { Ok(resp) => {
if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() { if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() {
logging!(info, Type::Service, true, "服务正在运行"); logging!(info, Type::Service, true, "服务正在运行");
Ok(true) Ok(())
} else { } else {
logging!( logging!(
warn, warn,
@@ -964,74 +964,12 @@ pub async fn is_service_running() -> Result<bool> {
resp.code, resp.code,
resp.msg resp.msg
); );
Ok(false) Ok(())
} }
} }
Err(err) => { Err(err) => {
logging!(error, Type::Service, true, "检查服务运行状态失败: {}", err); logging!(error, Type::Service, true, "检查服务运行状态失败: {}", err);
/* Err(err)
let error_type = err.root_cause().to_string();
logging!(
error,
Type::Service,
true,
"连接失败的根本原因: {}",
error_type
);
let socket_path = if cfg!(windows) {
r"\\.\pipe\clash-verge-service"
} else {
"/tmp/clash-verge-service.sock"
};
if cfg!(windows) {
logging!(
info,
Type::Service,
true,
"检查Windows命名管道: {}",
socket_path
);
} else {
let socket_exists = std::path::Path::new(socket_path).exists();
logging!(
info,
Type::Service,
true,
"检查Unix套接字文件: {} 是否存在: {}",
socket_path,
socket_exists
);
}
*/
Ok(false)
}
}
}
pub async fn is_service_available() -> Result<()> {
logging!(info, Type::Service, true, "开始检查服务是否可用");
match check_ipc_service_status().await {
Ok(resp) => {
if resp.code == 0 && resp.msg == "ok" && resp.data.is_some() {
logging!(info, Type::Service, true, "服务可用");
} else {
logging!(
warn,
Type::Service,
true,
"服务返回异常: code={}, msg={}",
resp.code,
resp.msg
);
}
Ok(())
}
Err(err) => {
logging!(error, Type::Service, true, "服务不可用: {}", err);
bail!("服务不可用: {}", err)
} }
} }
} }

View File

@@ -23,11 +23,13 @@ use parking_lot::Mutex;
use parking_lot::RwLock; use parking_lot::RwLock;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub use speed_rate::{SpeedRate, Traffic}; pub use speed_rate::{SpeedRate, Traffic};
use std::fs;
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use std::sync::Arc; use std::sync::Arc;
use std::time::{Duration, Instant}; use std::{
fs,
sync::atomic::{AtomicBool, Ordering},
time::{Duration, Instant},
};
use tauri::{ use tauri::{
menu::{CheckMenuItem, IsMenuItem, MenuEvent, MenuItem, PredefinedMenuItem, Submenu}, menu::{CheckMenuItem, IsMenuItem, MenuEvent, MenuItem, PredefinedMenuItem, Submenu},
tray::{MouseButton, MouseButtonState, TrayIconEvent}, tray::{MouseButton, MouseButtonState, TrayIconEvent},

View File

@@ -20,7 +20,7 @@ import {
import { useVerge } from "@/hooks/use-verge"; import { useVerge } from "@/hooks/use-verge";
import { useSystemState } from "@/hooks/use-system-state"; import { useSystemState } from "@/hooks/use-system-state";
import { showNotice } from "@/services/noticeService"; import { showNotice } from "@/services/noticeService";
import { isServiceAvailable } from "@/services/cmds"; import { getRunningMode } from "@/services/cmds";
import { mutate } from "swr"; import { mutate } from "swr";
const LOCAL_STORAGE_TAB_KEY = "clash-verge-proxy-active-tab"; const LOCAL_STORAGE_TAB_KEY = "clash-verge-proxy-active-tab";
@@ -140,32 +140,33 @@ export const ProxyTunCard: FC = () => {
const [activeTab, setActiveTab] = useState<string>( const [activeTab, setActiveTab] = useState<string>(
() => localStorage.getItem(LOCAL_STORAGE_TAB_KEY) || "system", () => localStorage.getItem(LOCAL_STORAGE_TAB_KEY) || "system",
); );
const [localServiceOk, setLocalServiceOk] = useState(false); const [localServiceOk, setLocalServiceOk] = useState(false);
const { verge } = useVerge(); const { verge } = useVerge();
const { isAdminMode } = useSystemState(); const { isAdminMode } = useSystemState();
const { enable_system_proxy, enable_tun_mode } = verge ?? {}; const { enable_system_proxy, enable_tun_mode } = verge ?? {};
const updateLocalStatus = async () => { const updateLocalStatus = async () => {
try { try {
const serviceStatus = await isServiceAvailable(); const runningMode = await getRunningMode();
const serviceStatus = runningMode === "Service";
setLocalServiceOk(serviceStatus); setLocalServiceOk(serviceStatus);
mutate("isServiceAvailable", serviceStatus, false); mutate("isServiceAvailable", serviceStatus, false);
} catch (error) { } catch (error) {
console.error("更新TUN状态失败:", error); console.error("更新TUN状态失败:", error);
} }
}; };
useEffect(() => { useEffect(() => {
updateLocalStatus(); updateLocalStatus();
}, []); }, []);
const isTunAvailable = localServiceOk || isAdminMode; const isTunAvailable = localServiceOk || isAdminMode;
const handleError = (err: Error) => { const handleError = (err: Error) => {
showNotice('error', err.message || err.toString()); showNotice("error", err.message || err.toString());
}; };
const handleTabChange = (tab: string) => { const handleTabChange = (tab: string) => {

View File

@@ -23,7 +23,6 @@ import {
uninstallService, uninstallService,
restartCore, restartCore,
stopCore, stopCore,
isServiceAvailable,
} from "@/services/cmds"; } from "@/services/cmds";
import { useLockFn } from "ahooks"; import { useLockFn } from "ahooks";
import { Button, Tooltip } from "@mui/material"; import { Button, Tooltip } from "@mui/material";
@@ -45,16 +44,10 @@ const SettingSystem = ({ onError }: Props) => {
const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy); const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy);
const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy); const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy);
const { data: serviceOk, mutate: mutateServiceAvailable } = useSWR( const { isAdminMode, isServiceMode, mutateRunningMode } = useSystemState();
"isServiceAvailable",
isServiceAvailable
);
const { isAdminMode, isSidecarMode, mutateRunningMode } = useSystemState(); // +++ isTunAvailable 现在使用 SWR 的 isServiceMode
const isTunAvailable = isServiceMode || isAdminMode;
// +++ isTunAvailable 现在使用 SWR 的 serviceOk
const isTunAvailable = serviceOk || isAdminMode;
const sysproxyRef = useRef<DialogRef>(null); const sysproxyRef = useRef<DialogRef>(null);
const tunRef = useRef<DialogRef>(null); const tunRef = useRef<DialogRef>(null);
@@ -80,19 +73,17 @@ const SettingSystem = ({ onError }: Props) => {
// 抽象服务操作逻辑 // 抽象服务操作逻辑
const handleServiceOperation = useLockFn( const handleServiceOperation = useLockFn(
async ( async ({
{ beforeMsg,
beforeMsg, action,
action, actionMsg,
actionMsg, successMsg,
successMsg, }: {
}: { beforeMsg: string;
beforeMsg: string; action: () => Promise<void>;
action: () => Promise<void>; actionMsg: string;
actionMsg: string; successMsg: string;
successMsg: string; }) => {
}
) => {
try { try {
showNotice("info", beforeMsg); showNotice("info", beforeMsg);
await stopCore(); await stopCore();
@@ -102,19 +93,17 @@ const SettingSystem = ({ onError }: Props) => {
showNotice("info", t("Restarting Core...")); showNotice("info", t("Restarting Core..."));
await restartCore(); await restartCore();
await mutateRunningMode(); await mutateRunningMode();
await mutateServiceAvailable();
} catch (err: any) { } catch (err: any) {
showNotice("error", err.message || err.toString()); showNotice("error", err.message || err.toString());
try { try {
showNotice("info", t("Try running core as Sidecar...")); showNotice("info", t("Try running core as Sidecar..."));
await restartCore(); await restartCore();
await mutateRunningMode(); await mutateRunningMode();
await mutateServiceAvailable();
} catch (e: any) { } catch (e: any) {
showNotice("error", e?.message || e?.toString()); showNotice("error", e?.message || e?.toString());
} }
} }
} },
); );
// 卸载系统服务 // 卸载系统服务
@@ -145,33 +134,32 @@ const SettingSystem = ({ onError }: Props) => {
<WarningRounded sx={{ color: "warning.main", mr: 1 }} /> <WarningRounded sx={{ color: "warning.main", mr: 1 }} />
</Tooltip> </Tooltip>
)} )}
{!serviceOk && !isAdminMode && ( {!isServiceMode && !isAdminMode && (
<Tooltip title={t("Install Service")}> <Tooltip title={t("Install Service")}>
<Button <Button
variant="outlined" variant="outlined"
color="primary" color="primary"
size="small" size="small"
onClick={installServiceAndRestartCore} onClick={installServiceAndRestartCore}
sx={{ mr: 1, minWidth: "32px", p: "4px" }} sx={{ mr: 1, minWidth: "32px", p: "4px" }}
> >
<BuildRounded fontSize="small" /> <BuildRounded fontSize="small" />
</Button> </Button>
</Tooltip> </Tooltip>
)} )}
{serviceOk && ( {isServiceMode && (
<Tooltip title={t("Uninstall Service")}> <Tooltip title={t("Uninstall Service")}>
<Button <Button
// variant="outlined" // variant="outlined"
color="secondary" color="secondary"
size="small" size="small"
onClick={onUninstallService} onClick={onUninstallService}
sx={{ mr: 1, minWidth: "32px", p: "4px" }} sx={{ mr: 1, minWidth: "32px", p: "4px" }}
> >
<DeleteForeverRounded fontSize="small" /> <DeleteForeverRounded fontSize="small" />
</Button> </Button>
</Tooltip> </Tooltip>
) )}
}
</> </>
} }
> >
@@ -187,12 +175,14 @@ const SettingSystem = ({ onError }: Props) => {
onGuard={(e) => { onGuard={(e) => {
if (!isTunAvailable) { if (!isTunAvailable) {
showNotice("error", t("TUN requires Service Mode or Admin Mode")); showNotice("error", t("TUN requires Service Mode or Admin Mode"));
return Promise.reject(new Error(t("TUN requires Service Mode or Admin Mode"))); return Promise.reject(
new Error(t("TUN requires Service Mode or Admin Mode")),
);
} }
return patchVerge({ enable_tun_mode: e }); return patchVerge({ enable_tun_mode: e });
}} }}
> >
<Switch edge="end" disabled={!isTunAvailable} /> <Switch edge="end" disabled={!isTunAvailable} />
</GuardState> </GuardState>
</SettingItem> </SettingItem>
<SettingItem <SettingItem

View File

@@ -23,12 +23,14 @@ export function useSystemState() {
}); });
// 获取系统服务状态 // 获取系统服务状态
const isServiceMode = runningMode === "Service";
const { data: isServiceOk = false } = useSWR( const { data: isServiceOk = false } = useSWR(
"isServiceAvailable", "isServiceAvailable",
isServiceAvailable, isServiceAvailable,
{ {
suspense: false, suspense: false,
revalidateOnFocus: false, revalidateOnFocus: false,
isPaused: () => !isServiceMode, // 仅在 Service 模式下请求
}, },
); );
@@ -36,7 +38,8 @@ export function useSystemState() {
runningMode, runningMode,
isAdminMode, isAdminMode,
isSidecarMode: runningMode === "Sidecar", isSidecarMode: runningMode === "Sidecar",
mutateRunningMode, isServiceMode: runningMode === "Service",
isServiceOk, isServiceOk,
mutateRunningMode,
}; };
} }