mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-05 16:22:08 +08:00
* refactor(core): type notice statuses behind the frozen wire contract * refactor(utils): unified retry and strategy-list helpers * refactor(feat): declarative effect registry for verge and clash patches * refactor(core): derive refresh announcements from transaction commit * refactor(core): fold tray, hotkey, autostart updates into effect ensures * refactor(utils): migrate remaining bounded retry loops * docs: add src-tauri architecture guardrails * refactor(core): coalesce burst refresh announcements * refactor(core): complete bounded service retry migration * ci(backend): add architecture ban gates * test(feat): freeze representative effect registry mappings * docs(backend): record dead wire contract entries * chore(core): document watcher exit conditions * fix(backend): preserve applied state across later failures * fix(config): retain runtime after an applied core replacement * refactor(backend): flatten refresh publication and retry policies * docs(backend): focus guardrails on architecture ownership * refactor(effects): use one execution order * fix(config): publish retained runtime and reconcile proxy settings
87 lines
3.0 KiB
Rust
87 lines
3.0 KiB
Rust
//! Reconciles TUN with current Core and Service availability.
|
|
|
|
use crate::core::notify::NoticeStatus;
|
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
use clash_verge_logging::{Type, logging};
|
|
use scopeguard::defer;
|
|
|
|
use crate::{
|
|
config::{Config, IVerge},
|
|
core::{handle::Handle, manager::RunningMode, runstate::RUN_STATE},
|
|
};
|
|
|
|
/// Prevents recursive runtime disable writes.
|
|
static DISABLING_TUN: AtomicBool = AtomicBool::new(false);
|
|
|
|
/// Turn TUN off when startup confirms the Service is absent, so the Core can start on Sidecar.
|
|
///
|
|
/// Runs before the runtime config is generated.
|
|
pub async fn reconcile_startup_tun_availability() {
|
|
// Read fresh state after prior config writes complete.
|
|
let _config_write = Config::lock_config_write().await;
|
|
let tun_enabled = Config::verge().await.data_arc().enable_tun_mode.unwrap_or(false);
|
|
if !RUN_STATE.state().startup_tun_should_be_disabled(tun_enabled) {
|
|
return;
|
|
}
|
|
|
|
logging!(
|
|
info,
|
|
Type::Setup,
|
|
"Service is not installed; turning TUN mode off so the Core can start on Sidecar"
|
|
);
|
|
// Write the preference only: a patch would reach update_config_checked, which with no Core to
|
|
// reload starts one ahead of the rest of startup, and rolls the write back if that fails.
|
|
if let Err(error) = Config::disable_tun_and_persist().await {
|
|
logging!(error, Type::Setup, "failed to turn TUN mode off at startup: {error:#}");
|
|
}
|
|
}
|
|
|
|
/// Disable TUN when the current settled Run State cannot support it.
|
|
pub async fn reconcile_tun_availability() {
|
|
if DISABLING_TUN.load(Ordering::Acquire) {
|
|
return;
|
|
}
|
|
|
|
// Re-read state and committed config after prior writes complete.
|
|
let config_write = Config::lock_config_write().await;
|
|
let state = RUN_STATE.state();
|
|
|
|
// Startup uses the narrower path above, before a Core is running.
|
|
if matches!(state.mode, RunningMode::NotRunning) {
|
|
return;
|
|
}
|
|
|
|
// Legacy writers may still hold an uncommitted draft.
|
|
let tun_enabled = Config::verge().await.data_arc().enable_tun_mode.unwrap_or(false);
|
|
if !state.tun_should_be_disabled(tun_enabled) {
|
|
return;
|
|
}
|
|
|
|
// The flag coalesces newly spawned tasks while the config lock serializes writers.
|
|
DISABLING_TUN.store(true, Ordering::Release);
|
|
defer! {
|
|
DISABLING_TUN.store(false, Ordering::Release);
|
|
}
|
|
|
|
logging!(
|
|
info,
|
|
Type::Core,
|
|
"TUN mode cannot work in the current run state; turning it off"
|
|
);
|
|
let patch = IVerge {
|
|
enable_tun_mode: Some(false),
|
|
..IVerge::default()
|
|
};
|
|
|
|
// Skip recursive reconciliation for this internal patch.
|
|
match super::apply_verge_patch_locked(&config_write, &patch, false).await {
|
|
Ok(()) => Handle::notice(NoticeStatus::TunModeAutoDisabled, ""),
|
|
Err(error) => {
|
|
logging!(error, Type::Core, "failed to turn TUN mode off: {error:#}");
|
|
Handle::notice(NoticeStatus::TunModeAutoDisableFailed, "");
|
|
}
|
|
}
|
|
}
|