From 1b6b669b9b82d1f81b887a32055f19c53d3bb8bf Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Sat, 10 Jan 2026 02:14:01 +0000 Subject: Add naughty list for git remotes with persistent SSL/DNS errors Implement domain-level naughty list tracking for git remotes, reusing the existing NaughtyListTracker from relay sync. This prevents repeated attempts to fetch from git domains with persistent infrastructure issues (SSL/TLS certificate errors, DNS failures). Changes: - Updated NaughtyListTracker to track both relay URLs and git domains - Added git_naughty_list field to RealSyncContext for error classification - Modified fetch_oids() to classify git fetch errors and record naughty domains - Updated sync_identifier_next_url() to filter out naughty domains during URL selection - Added git_naughty_list parameter to ThrottleManager for domain queue processing - Threaded naughty list through start_sync_loop and all sync functions - Updated all tests to pass naughty list parameter The naughty list uses 12-hour expiration (configurable) to allow domains to recover from infrastructure issues. First occurrence logs WARN, repeats log DEBUG. --- src/purgatory/sync/context.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/purgatory/sync/context.rs') diff --git a/src/purgatory/sync/context.rs b/src/purgatory/sync/context.rs index e61de01..3c2c683 100644 --- a/src/purgatory/sync/context.rs +++ b/src/purgatory/sync/context.rs @@ -187,6 +187,9 @@ use tracing::debug; use crate::nostr::builder::SharedDatabase; use crate::nostr::events::RepositoryState; use crate::purgatory::Purgatory; +use crate::sync::naughty_list::NaughtyListTracker; + +use super::functions::extract_domain; /// Real implementation of `SyncContext` that connects to actual systems. /// @@ -210,6 +213,9 @@ pub struct RealSyncContext { /// Local relay for notifying WebSocket subscribers local_relay: Option, + + /// Naughty list tracker for git remote domains with persistent errors + git_naughty_list: Arc, } impl RealSyncContext { @@ -221,12 +227,14 @@ impl RealSyncContext { /// * `git_data_path` - Base path for git repositories /// * `our_domain` - Our domain to exclude from clone URLs /// * `local_relay` - Local relay for WebSocket notifications + /// * `git_naughty_list` - Naughty list tracker for git remote domains pub fn new( purgatory: Arc, database: SharedDatabase, git_data_path: PathBuf, our_domain: Option, local_relay: Option, + git_naughty_list: Arc, ) -> Self { Self { purgatory, @@ -234,8 +242,14 @@ impl RealSyncContext { git_data_path, our_domain_value: our_domain, local_relay, + git_naughty_list, } } + + /// Get reference to the git naughty list tracker + pub fn git_naughty_list(&self) -> &Arc { + &self.git_naughty_list + } } #[async_trait] @@ -344,6 +358,7 @@ impl SyncContext for RealSyncContext { let repo_path = repo_path.to_path_buf(); let url = url.to_string(); let missing_oids: Vec = missing.into_iter().cloned().collect(); + let naughty_list = self.git_naughty_list.clone(); tokio::task::spawn_blocking(move || -> Result> { // git fetch ... - fetch all OIDs in one command @@ -370,6 +385,29 @@ impl SyncContext for RealSyncContext { } Ok(result) => { let stderr = String::from_utf8_lossy(&result.stderr); + + // Extract domain and classify error for naughty list + if let Some(domain) = extract_domain(&url) { + if let Some(category) = NaughtyListTracker::classify_error(&stderr) { + let is_new = naughty_list.record(&domain, category, stderr.to_string()); + + if is_new { + tracing::warn!( + domain = %domain, + category = %category, + error = %stderr, + "Git remote domain added to naughty list" + ); + } else { + debug!( + domain = %domain, + category = %category, + "Git remote domain still on naughty list" + ); + } + } + } + Err(anyhow::anyhow!("git fetch failed: {}", stderr)) } Err(e) => Err(anyhow::anyhow!("git fetch command error: {}", e)), -- cgit v1.2.3