feat: 410 Gone Handling

This commit is contained in:
Jacob Taylor committed 2026-11-11 13:52:27 -08:00
1 parent 67f31756b9
commit b2d5aa8625
4 files changed
+30 -15

No files matched your search

+1
View File
@@ -0,0 +1 @@
Added support for servers returning 410 gone to indicate they are no longer serving a Matrix server (MSC4188). Contributed by @nex and @silversys
+16 -3
View File
@@ -1,4 +1,9 @@
use std::{borrow::Cow, fmt::Debug, mem, time::Instant};
use std::{
borrow::Cow,
fmt::Debug,
mem,
time::{Duration, Instant},
};
use conduwuit::{
Err, Error, Result, debug, debug_error, debug_info, debug_warn, err, metrics::KeyValue,
@@ -133,12 +138,20 @@ impl super::Service {
self.ensure_remote_is_healthy(dest)?;
/// How long to mark a server as unhealthy before attempting
/// re-resolution
const UNHEALTHY_TIMEOUT: Duration = Duration::from_hours(24 * 90);
let actual = self
.services
.client
.matrix_resolver
.resolve_server(dest.as_str())
.await?;
.await
.inspect_err(|_| {
self.hit_unhealthy(dest.to_owned(), Some(UNHEALTHY_TIMEOUT));
self.mark_destination_stale(dest);
})?;
let request = Request::try_from(request.try_into_http_request::<Vec<u8>>(
actual.base_url().as_str(),
@@ -210,7 +223,7 @@ impl super::Service {
if self.should_mark_stale(&wrapped) {
debug_info!("{dest} is unhealthy & stale due to a connect error");
self.mark_destination_stale(dest);
self.hit_unhealthy(dest.to_owned());
self.hit_unhealthy(dest.to_owned(), None);
}
let Error::Reqwest(unwrapped) = wrapped else {
unreachable!("wrapped reqwest error must unwrap to a reqwest error");
+11 -10
View File
@@ -92,7 +92,7 @@ impl Service {
/// retry count is incremented and next retry window is updated.
///
/// Does not update the marker if the backoff period is already in effect.
pub fn hit_unhealthy(&self, server_name: OwnedServerName) {
pub fn hit_unhealthy(&self, server_name: OwnedServerName, next_attempt: Option<Duration>) {
if server_name == self.services.server.name {
return;
}
@@ -109,7 +109,8 @@ impl Service {
}
*retries = retries.saturating_add(1);
let next_interval = self.services.server.config.sender_retry_backoff(*retries);
let next_interval = next_attempt
.unwrap_or_else(|| self.services.server.config.sender_retry_backoff(*retries));
*next_retry = millis_from_now(next_interval);
debug!(
"{} is (now) unhealthy ({} retries, blocked until: {})",
@@ -200,14 +201,14 @@ impl Service {
}
match error.status_code() {
// Some special servers account for this specifically
| StatusCode::MISDIRECTED_REQUEST
// Common error codes observed for misdirected requests
// | StatusCode::NOT_FOUND This one can be encountered naturally
| StatusCode::METHOD_NOT_ALLOWED
| StatusCode::IM_A_TEAPOT => true,
_ => false,
}
// Some special servers account for this specifically
| StatusCode::MISDIRECTED_REQUEST
// Common error codes observed for misdirected requests
// | StatusCode::NOT_FOUND This one can be encountered naturally
| StatusCode::METHOD_NOT_ALLOWED
| StatusCode::IM_A_TEAPOT => true,
_ => false,
}
}
/// Returns a clone of the internal remote health tracking map.
+2 -2
View File
@@ -149,10 +149,10 @@ impl Service {
{
debug!("{dest} is now unhealthy & stale due to a connect error: {e:?}");
self.services.federation.mark_destination_stale(dest);
self.services.federation.hit_unhealthy(dest.clone());
self.services.federation.hit_unhealthy(dest.clone(), None);
} else if e.status_code() != StatusCode::OK {
debug!("{dest} is now unhealthy due to error response: {e:?}");
self.services.federation.hit_unhealthy(dest.clone());
self.services.federation.hit_unhealthy(dest.clone(), None);
}
}
Self::handle_response_err(dest, statuses, &e);