diff --git a/src-tauri/src/core/logger.rs b/src-tauri/src/core/logger.rs index d227d8c78..5119545c0 100644 --- a/src-tauri/src/core/logger.rs +++ b/src-tauri/src/core/logger.rs @@ -17,11 +17,15 @@ use log::{Level, LevelFilter, Record}; use parking_lot::{Mutex, RwLock}; use crate::{ - core::service, + core::{CoreManager, manager::RunningMode, service}, singleton, utils::dirs::{self, sidecar_log_dir}, }; +const fn should_sync_service_writer(running_mode: RunningMode) -> bool { + matches!(running_mode, RunningMode::Service) +} + pub struct Logger { handle: Arc>>, sidecar_file_writer: Arc>>, @@ -178,14 +182,17 @@ impl Logger { let sidecar_writer = self.generate_sidecar_writer()?; *self.sidecar_file_writer.write() = Some(sidecar_writer); - // update service writer config - if service::SERVICE_MANAGER.is_ready_cached() { - service::update_writer_by_service(&clash_verge_service_ipc::WriterConfig { + // The service writer is auxiliary to the local logger. Synchronize it only + // for an active service session and do not roll back local settings on failure. + if should_sync_service_writer(*CoreManager::global().get_running_mode()) + && let Err(error) = service::update_writer_by_service(&clash_verge_service_ipc::WriterConfig { directory: String::new(), max_log_size: log_max_size * 1024, max_log_files: log_max_count, }) - .await?; + .await + { + logging!(warn, Type::Service, "failed to update service writer config: {error:#}"); } Ok(()) @@ -224,3 +231,16 @@ impl Logger { } } } + +#[cfg(test)] +mod tests { + use super::should_sync_service_writer; + use crate::core::manager::RunningMode; + + #[test] + fn service_writer_sync_requires_service_running_mode() { + assert!(should_sync_service_writer(RunningMode::Service)); + assert!(!should_sync_service_writer(RunningMode::Sidecar)); + assert!(!should_sync_service_writer(RunningMode::NotRunning)); + } +} diff --git a/src-tauri/src/core/service.rs b/src-tauri/src/core/service.rs index 4cd62c781..17bf31092 100644 --- a/src-tauri/src/core/service.rs +++ b/src-tauri/src/core/service.rs @@ -107,7 +107,6 @@ const fn classify_service_install_state(current: CurrentServiceProbe, has_instal match current { CurrentServiceProbe::Ready => ServiceInstallState::Ready, CurrentServiceProbe::VersionMismatch => ServiceInstallState::NeedsReinstall, - CurrentServiceProbe::Unavailable if has_install_marker => ServiceInstallState::NeedsReinstall, CurrentServiceProbe::Unavailable => ServiceInstallState::Unavailable, CurrentServiceProbe::Missing if has_install_marker => ServiceInstallState::NeedsReinstall, CurrentServiceProbe::Missing => ServiceInstallState::NotInstalled, @@ -304,7 +303,7 @@ fn trusted_service_evidence() -> Result { } async fn detect_service_install_state() -> ServiceInstallState { - let markers = match trusted_service_evidence() { + let has_trusted_install_marker = match trusted_service_evidence() { Ok(exists) => exists, Err(error) => { logging!( @@ -316,7 +315,7 @@ async fn detect_service_install_state() -> ServiceInstallState { } }; - if !markers { + if !has_trusted_install_marker { return classify_service_install_state(CurrentServiceProbe::Missing, false); } @@ -329,7 +328,7 @@ async fn detect_service_install_state() -> ServiceInstallState { } }; - classify_service_install_state(current, markers) + classify_service_install_state(current, has_trusted_install_marker) } pub struct ServiceManager { @@ -1412,7 +1411,6 @@ impl ServiceManager { } } - #[cfg(target_os = "windows")] pub async fn confirm_ready(&self) -> Result<()> { let reply = probe_service_version_once() .await @@ -1545,14 +1543,7 @@ impl ServiceManager { } pub async fn refresh(&self) -> Result<()> { - self.run_operation(async { - apply_service_version_result( - self, - probe_service_version_once().await, - "failed to refresh service protocol", - ) - }) - .await + self.run_operation(async { self.confirm_ready().await }).await } pub async fn handle_service_status(&self, status: ServiceStatus) -> Result<()> { @@ -2204,7 +2195,7 @@ mod tests { ); assert_eq!( classify_service_install_state(CurrentServiceProbe::Unavailable, true), - ServiceInstallState::NeedsReinstall + ServiceInstallState::Unavailable ); } diff --git a/src/components/proxy/proxy-empty-state-model.ts b/src/components/proxy/proxy-empty-state-model.ts index 16c64708c..537d0eb80 100644 --- a/src/components/proxy/proxy-empty-state-model.ts +++ b/src/components/proxy/proxy-empty-state-model.ts @@ -29,7 +29,7 @@ interface ProxyEmptyStateInput { const isSubscriptionProfile = (item: { type?: string }): boolean => item.type === 'remote' || item.type === 'local' -export const hasRenderableProxyContent = ( +const hasRenderableProxyContent = ( proxyView: ProxyViewV1 | undefined, mode: string, isChainMode: boolean, diff --git a/src/components/shared/proxy-control-switches.tsx b/src/components/shared/proxy-control-switches.tsx index b8f7c4746..807fc25f6 100644 --- a/src/components/shared/proxy-control-switches.tsx +++ b/src/components/shared/proxy-control-switches.tsx @@ -135,7 +135,7 @@ const ProxyControlSwitches = ({ const { uninstallServiceAndStartSidecar } = useServiceUninstaller() const { indicator: systemProxyIndicator, toggleSystemProxy } = useSystemProxyState() - const { isServiceOk, isTunModeAvailable, mutateSystemState } = + const { isServiceInstallReady, isTunModeAvailable, mutateSystemState } = useSystemState() const sysproxyRef = useRef(null) @@ -225,7 +225,7 @@ const ProxyControlSwitches = ({ /> )} - {isServiceOk && ( + {isServiceInstallReady && ( => { return { runningMode, isAdminMode, - isServiceOk: serviceInstallState === 'ready', + isServiceInstallReady: serviceInstallState === 'ready', serviceInstallState, } } const isServiceChoicePending = ( state: ServiceInstallState | null, - serviceAvailable: boolean, + serviceInstallReady: boolean, queryFailed: boolean, ) => queryFailed || state === 'sidecarAllowed' || - !(state === 'notInstalled' || (state === 'ready' && serviceAvailable)) + !(state === 'notInstalled' || (state === 'ready' && serviceInstallReady)) // Grace period for service initialization during startup const STARTUP_GRACE_MS = 10_000 @@ -81,17 +81,18 @@ export function useSystemState() { const isSidecarMode = systemState.runningMode === 'Sidecar' const isServiceMode = systemState.runningMode === 'Service' - const isTunModeAvailable = systemState.isAdminMode || systemState.isServiceOk + const isTunModeAvailable = + systemState.isAdminMode || systemState.isServiceInstallReady const serviceChoicePending = isServiceChoicePending( systemState.serviceInstallState, - systemState.isServiceOk, + systemState.isServiceInstallReady, systemStateError !== undefined, ) return { runningMode: systemState.runningMode, isAdminMode: systemState.isAdminMode, - isServiceOk: systemState.isServiceOk, + isServiceInstallReady: systemState.isServiceInstallReady, isSidecarMode, isServiceMode, isTunModeAvailable,