refactor: Unify retry backoff helpers

This commit is contained in:
Erwan Leboucher authored and Jade Ellis committed 2026-10-12 11:14:01 +01:00
1 parent bd005edd59
commit fe0ab62124
7 files changed
+72 -31

No files matched your search

+6 -9
View File
@@ -8,7 +8,10 @@ use std::{
use assign::assign;
use async_trait::async_trait;
use conduwuit::{Error, Result, Server, SyncRwLock, debug, utils::millis_since_unix_epoch};
use conduwuit::{
Error, Result, Server, SyncRwLock, debug,
utils::{millis_from_now, millis_since_unix_epoch},
};
pub(crate) use execute::FederationPathBuilderInput;
use http::StatusCode;
use ruma::{
@@ -105,15 +108,9 @@ impl Service {
return;
}
let min = Duration::from_secs(self.services.server.config.sender_retry_backoff_base);
let max = Duration::from_secs(self.services.server.config.sender_retry_backoff_limit);
*retries = retries.saturating_add(1);
let next_interval = min.saturating_mul(*retries).min(max);
*next_retry = unix_now.saturating_add(
u64::try_from(next_interval.as_millis())
.expect("backoff milliseconds should not exceed u64::MAX"),
);
let next_interval = self.services.server.config.sender_retry_backoff(*retries);
*next_retry = millis_from_now(next_interval);
debug!(
"{} is (now) unhealthy ({} retries, blocked until: {})",
sn2, *retries, *next_retry
+3 -4
View File
@@ -132,7 +132,7 @@ impl Service {
let state = WebPushState {
activated: false,
ack_token: Some(token.clone()),
token_expires_at: utils::millis_since_unix_epoch().saturating_add(ACK_TOKEN_TTL_MS),
token_expires_at: utils::millis_from_now(Duration::from_millis(ACK_TOKEN_TTL_MS)),
};
self.put_webpush_state(sender, pusher.ids.pushkey.as_str(), &state);
@@ -301,7 +301,7 @@ impl Service {
}
let delay = retry_after
.unwrap_or_else(|| RETRY_BASE.saturating_mul(attempt))
.unwrap_or_else(|| utils::linear_backoff(RETRY_BASE, RETRY_MAX, attempt))
.min(RETRY_MAX);
sleep(delay).await;
attempt = attempt.saturating_add(1);
@@ -413,8 +413,7 @@ impl Service {
|retry_after| retry_after.min(BACKOFF_MAX),
);
backoff.next_attempt_at = utils::millis_since_unix_epoch()
.saturating_add(delay.as_millis().try_into().unwrap_or(u64::MAX));
backoff.next_attempt_at = utils::millis_from_now(delay);
self.db.senderkey_webpushbackoff.put(key, Json(&backoff));
}
+7 -14
View File
@@ -13,12 +13,7 @@ mod resolve_state;
mod state_at_incoming;
mod upgrade_outlier_pdu;
use std::{
collections::HashMap,
fmt::Write,
sync::Arc,
time::{Duration, Instant},
};
use std::{collections::HashMap, fmt::Write, sync::Arc, time::Instant};
use assign::assign;
use async_trait::async_trait;
@@ -149,7 +144,11 @@ impl Service {
let Some((retry_count, last_retry)) = map.get(event_id) else {
return Ok(());
};
let next_retry = calc_next_retry(&self.services.server.config, *retry_count);
let next_retry = self
.services
.server
.config
.sender_retry_backoff(*retry_count);
if last_retry.elapsed() >= next_retry {
Ok(())
} else {
@@ -169,7 +168,7 @@ impl Service {
let mut map = self.failed_pdu_pulls.write();
map.entry(event_id)
.and_modify(|(retries, last_retry)| {
let next_retry = calc_next_retry(&self.services.server.config, *retries);
let next_retry = self.services.server.config.sender_retry_backoff(*retries);
if next_retry > last_retry.elapsed() {
// Don't increment the retry if a retry was illegal.
// This can happen if an event was fetched multiple times
@@ -201,9 +200,3 @@ fn get_room_version_rules<Pdu: Event>(create_event: &Pdu) -> Result<RoomVersionR
Ok(room_version_rules)
}
fn calc_next_retry(config: &conduwuit::Config, retries: u32) -> Duration {
let min = Duration::from_secs(config.sender_retry_backoff_base);
let max = Duration::from_secs(config.sender_retry_backoff_limit);
min.saturating_mul(retries).min(max)
}
+1 -3
View File
@@ -450,9 +450,7 @@ impl Service {
.entry(dest.clone())
.and_modify(|e| match e {
| TransactionStatus::Failed(tries, time) => {
let min = Duration::from_secs(self.server.config.sender_retry_backoff_base);
let max = Duration::from_secs(self.server.config.sender_retry_backoff_limit);
let retry_after = min.saturating_mul(*tries).min(max);
let retry_after = self.server.config.sender_retry_backoff(*tries);
if time.elapsed() < retry_after {
debug_warn!("Not retrying destination for another {retry_after:?}");
allow = false;