mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-12 19:56:48 +00:00
feat: 410 Gone Handling
This commit is contained in:
1 parent
67f31756b9
commit
b2d5aa8625
4 files changed
+30
-15
No files matched your search
@@ -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
|
||||
@@ -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");
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user