refactor(core): elegant retry (#5113)

This commit is contained in:
Sline
2025-10-18 10:12:36 +08:00
committed by GitHub
parent fc99f24802
commit a1c0a09423

View File

@@ -26,12 +26,9 @@ use flexi_logger::DeferredNow;
use log::Level; use log::Level;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Duration};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use std::{ use std::time::Instant;
sync::atomic::{AtomicUsize, Ordering}, use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Duration};
time::Instant,
};
use tauri_plugin_mihomo::Error as MihomoError; use tauri_plugin_mihomo::Error as MihomoError;
use tauri_plugin_shell::ShellExt; use tauri_plugin_shell::ShellExt;
use tokio::time::sleep; use tokio::time::sleep;
@@ -976,29 +973,28 @@ impl CoreManager {
}; };
backoff_strategy.reset(); backoff_strategy.reset();
let attempts = Arc::new(AtomicUsize::new(0)); let mut attempts = 0usize;
let attempts_for_retry = Arc::clone(&attempts);
let operation = || { let operation = || {
let attempts = Arc::clone(&attempts_for_retry); attempts += 1;
let attempt = attempts;
async move { async move {
let attempt = attempts.fetch_add(1, Ordering::Relaxed);
let mut manager = SERVICE_MANAGER.lock().await; let mut manager = SERVICE_MANAGER.lock().await;
if matches!(manager.current(), ServiceStatus::Ready) { if matches!(manager.current(), ServiceStatus::Ready) {
if attempt > 0 { if attempt > 1 {
logging!( logging!(
info, info,
Type::Core, Type::Core,
"Service became ready for TUN after {} attempt(s)", "Service became ready for TUN after {} attempt(s)",
attempt + 1 attempt
); );
} }
return Ok(()); return Ok(());
} }
if attempt == 0 { if attempt == 1 {
logging!( logging!(
info, info,
Type::Core, Type::Core,
@@ -1015,7 +1011,7 @@ impl CoreManager {
debug, debug,
Type::Core, Type::Core,
"Service connection attempt {} failed while waiting for TUN: {}", "Service connection attempt {} failed while waiting for TUN: {}",
attempt + 1, attempt,
err err
); );
return Err(BackoffError::transient(err)); return Err(BackoffError::transient(err));
@@ -1027,7 +1023,7 @@ impl CoreManager {
info, info,
Type::Core, Type::Core,
"Service became ready for TUN after {} attempt(s)", "Service became ready for TUN after {} attempt(s)",
attempt + 1 attempt
); );
return Ok(()); return Ok(());
} }
@@ -1036,7 +1032,7 @@ impl CoreManager {
debug, debug,
Type::Core, Type::Core,
"Service not ready after attempt {}; retrying with backoff", "Service not ready after attempt {}; retrying with backoff",
attempt + 1 attempt
); );
Err(BackoffError::transient(anyhow!("Service not ready yet"))) Err(BackoffError::transient(anyhow!("Service not ready yet")))
@@ -1046,14 +1042,13 @@ impl CoreManager {
let wait_started = Instant::now(); let wait_started = Instant::now();
if let Err(err) = backoff::future::retry(backoff_strategy, operation).await { if let Err(err) = backoff::future::retry(backoff_strategy, operation).await {
let total_attempts = attempts.load(Ordering::Relaxed);
let waited_ms = wait_started.elapsed().as_millis(); let waited_ms = wait_started.elapsed().as_millis();
logging!( logging!(
warn, warn,
Type::Core, Type::Core,
"Service still not ready after waiting approximately {} ms ({} attempt(s)); falling back to sidecar mode: {}", "Service still not ready after waiting approximately {} ms ({} attempt(s)); falling back to sidecar mode: {}",
waited_ms, waited_ms,
total_attempts, attempts,
err err
); );
} }