diff --git a/src/crawler/list_repos.rs b/src/crawler/list_repos.rs index d457a40..034a41b 100644 --- a/src/crawler/list_repos.rs +++ b/src/crawler/list_repos.rs @@ -3,8 +3,8 @@ use crate::db::{Db, keys}; use crate::state::AppState; use crate::util::throttle::{OrFailure, ThrottleHandle, Throttler}; use crate::util::{ - ErrorForStatus, RetryOutcome, RetryWithBackoff, WatchEnabledExt, is_tls_cert_error, - parse_retry_after, + ErrorForStatus, RetryOutcome, RetryWithBackoff, WatchEnabledExt, is_status_their_fault, + is_tls_cert_error, parse_retry_after, }; use chrono::{DateTime, TimeDelta, Utc}; use fjall::OwnedWriteBatch; @@ -121,16 +121,8 @@ fn is_throttle_worthy(e: &reqwest::Error) -> bool { src = s.source(); } - e.status().map_or(false, |s| { - matches!( - s, - StatusCode::BAD_GATEWAY - | StatusCode::SERVICE_UNAVAILABLE - | StatusCode::GATEWAY_TIMEOUT - | crate::util::CONNECTION_TIMEOUT - | crate::util::SITE_FROZEN - ) - }) + e.status() + .map_or(false, |s| is_status_their_fault(s.as_u16())) } /// shared describeRepo signal-checking logic used by both relay and retry producers. diff --git a/src/ingest/firehose.rs b/src/ingest/firehose.rs index 70bd6ea..5219231 100644 --- a/src/ingest/firehose.rs +++ b/src/ingest/firehose.rs @@ -3,7 +3,9 @@ use crate::ingest::stream::{FirehoseError, FirehoseStream, SubscribeReposMessage use crate::ingest::{BufferTx, IngestMessage}; use crate::state::AppState; use crate::util::throttle::ThrottleHandle; -use crate::util::{WatchEnabledExt, is_timeout, is_tls_cert_error, is_tls_error_our_fault}; +use crate::util::{ + WatchEnabledExt, is_status_their_fault, is_timeout, is_tls_cert_error, is_tls_error_their_fault, +}; use jacquard_common::IntoStatic; use jacquard_common::types::did::Did; use miette::{IntoDiagnostic, Result}; @@ -13,6 +15,7 @@ use std::sync::atomic::Ordering; use std::time::Duration; use tokio::sync::watch; use tokio_websockets::Error as WsError; +use tokio_websockets::upgrade::Error as WsUpgradeError; use tracing::{Span, debug, error, info, trace, warn}; use url::Url; @@ -24,19 +27,13 @@ fn is_throttle_worthy(e: &WsError) -> bool { } match e { - WsError::Rustls(e) if is_tls_error_our_fault(e) => return true, + WsError::Rustls(e) if is_tls_error_their_fault(e) => return true, WsError::Io(io_err) if is_tls_cert_error(io_err) => return true, WsError::CannotResolveHost => return true, - WsError::Upgrade(tokio_websockets::upgrade::Error::DidNotSwitchProtocols(status)) => { - return matches!( - *status, - 502 // BAD_GATEWAY - | 503 // SERVICE_UNAVAILABLE - | 504 // GATEWAY_TIMEOUT - | 522 // CONNECTION_TIMEOUT - | 530 // SITE_FROZEN - | 404 // NOT FOUND - ); + WsError::Upgrade(WsUpgradeError::DidNotSwitchProtocols(status)) + if is_status_their_fault(*status) => + { + return true; } WsError::Protocol(_) | WsError::PayloadTooLong { .. } => return true, _ => {} diff --git a/src/util/mod.rs b/src/util/mod.rs index be6bf9e..d718753 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -41,7 +41,7 @@ pub fn is_tls_cert_error(io_err: &std::io::Error) -> bool { return false; }; if let Some(rustls_err) = inner.downcast_ref::() { - return is_tls_error_our_fault(rustls_err); + return is_tls_error_their_fault(rustls_err); } if let Some(nested_io) = inner.downcast_ref::() { return is_tls_cert_error(nested_io); @@ -49,7 +49,7 @@ pub fn is_tls_cert_error(io_err: &std::io::Error) -> bool { false } -pub fn is_tls_error_our_fault(e: &rustls::Error) -> bool { +pub fn is_tls_error_their_fault(e: &rustls::Error) -> bool { use rustls::Error::*; matches!( *e, @@ -71,6 +71,19 @@ pub fn is_tls_error_our_fault(e: &rustls::Error) -> bool { ) } +pub fn is_status_their_fault(status: u16) -> bool { + return matches!( + status, + 502 // BAD_GATEWAY + | 503 // SERVICE_UNAVAILABLE + | 504 // GATEWAY_TIMEOUT + | 522 // CONNECTION_TIMEOUT + | 525 // SSL_HANDSHAKE_FAILURE + | 530 // SITE_FROZEN + | 404 // NOT FOUND: we know its not our fault because we use known xrpcs.. + ); +} + /// outcome of [`RetryWithBackoff::retry`] when the operation does not succeed. pub enum RetryOutcome { /// ratelimited after exhausting all retries @@ -190,6 +203,12 @@ pub const SITE_FROZEN: StatusCode = unsafe { _ => std::hint::unreachable_unchecked(), } }; +pub const SSL_HANDSHAKE_FAILURE: StatusCode = unsafe { + match StatusCode::from_u16(525) { + Ok(s) => s, + _ => std::hint::unreachable_unchecked(), + } +}; pub fn ser_status_code(s: &Option, ser: S) -> Result { match s {