Files
clash-verge-rev/src-tauri/src/feat/config.rs
T
Tunglies 0cae907de6 fix(config): wait for pending configuration writes
Serialize Verge patches behind the active configuration writer so toggling the system proxy after TUN does not fail immediately on lock contention.

CLose: #6613, #8481, #8357
2026-11-01 16:13:11 +08:00

57 lines
1.7 KiB
Rust

use crate::config::{Config, IVerge};
use anyhow::Result;
use clash_verge_draft::SharedDraft;
use serde_yaml_ng::Mapping;
use tokio::sync::MutexGuard;
pub async fn patch_clash(patch: &Mapping) -> Result<()> {
let config_write = Config::try_lock_config_write()?;
super::executor::apply(
&config_write,
super::executor::Patch::Clash(patch),
super::effects::clash_effects(patch),
)
.await
}
/// Apply a patch, then reconcile TUN when its setting changes.
///
/// TUN patches do not always produce a Run State transition, so reconciliation is explicit.
pub async fn patch_verge(patch: &IVerge, not_save_file: bool) -> Result<()> {
apply_verge_patch(patch, not_save_file).await?;
if patch.enable_tun_mode.is_some() {
super::reconcile_tun_availability().await;
}
Ok(())
}
/// Apply a patch without post-update reconciliation.
pub(super) async fn apply_verge_patch(patch: &IVerge, not_save_file: bool) -> Result<()> {
let config_write = Config::lock_config_write().await;
apply_verge_patch_locked(&config_write, patch, not_save_file).await
}
/// Apply a patch with the shared configuration write lock already held.
/// Callers must pass the guard returned by [`Config::lock_config_write`].
pub(super) async fn apply_verge_patch_locked(
_config_write: &MutexGuard<'_, ()>,
patch: &IVerge,
not_save_file: bool,
) -> Result<()> {
super::executor::apply(
_config_write,
super::executor::Patch::Verge {
patch,
persist: !not_save_file,
},
super::effects::verge_effects(patch),
)
.await
}
pub async fn fetch_verge_config() -> Result<SharedDraft<IVerge>> {
let draft = Config::verge().await;
let data = draft.data_arc();
Ok(data)
}