mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-13 20:26:52 +00:00
refactor: Unify retry backoff helpers
This commit is contained in:
1 parent
bd005edd59
commit
fe0ab62124
7 files changed
+72
-31
No files matched your search
@@ -7,6 +7,7 @@ use std::{
|
||||
collections::{BTreeMap, BTreeSet, HashMap},
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
path::PathBuf,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use conduwuit_macros::config_example_generator;
|
||||
@@ -2981,6 +2982,16 @@ const DEPRECATED_KEYS: &[&str] = &[
|
||||
];
|
||||
|
||||
impl Config {
|
||||
/// Returns the capped linear retry delay for a federation send attempt.
|
||||
#[must_use]
|
||||
pub fn sender_retry_backoff(&self, attempt: u32) -> Duration {
|
||||
crate::utils::linear_backoff(
|
||||
Duration::from_secs(self.sender_retry_backoff_base),
|
||||
Duration::from_secs(self.sender_retry_backoff_limit),
|
||||
attempt,
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the base domain to use for user-facing URLs.
|
||||
#[must_use]
|
||||
pub fn get_client_domain(&self) -> Url {
|
||||
|
||||
@@ -37,7 +37,10 @@ pub use self::{
|
||||
stream::{IterStream, ReadyExt, Tools as StreamTools, TryReadyExt},
|
||||
string::{str_from_bytes, string_from_bytes},
|
||||
sys::compute::available_parallelism,
|
||||
time::{now_millis as millis_since_unix_epoch, timepoint_ago, timepoint_from_now},
|
||||
time::{
|
||||
linear_backoff, millis_from_now, now_millis as millis_since_unix_epoch, timepoint_ago,
|
||||
timepoint_from_now,
|
||||
},
|
||||
};
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -16,6 +16,20 @@ pub fn now_millis() -> u64 {
|
||||
.as_millis() as u64
|
||||
}
|
||||
|
||||
/// Returns a capped linear retry delay for a failed attempt.
|
||||
#[must_use]
|
||||
pub fn linear_backoff(base: Duration, limit: Duration, attempt: u32) -> Duration {
|
||||
base.saturating_mul(attempt).min(limit)
|
||||
}
|
||||
|
||||
/// Returns a saturated Unix-millisecond deadline after `duration`.
|
||||
#[must_use]
|
||||
pub fn millis_from_now(duration: Duration) -> u64 { add_millis(now_millis(), duration) }
|
||||
|
||||
fn add_millis(now: u64, duration: Duration) -> u64 {
|
||||
now.saturating_add(u64::try_from(duration.as_millis()).unwrap_or(u64::MAX))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn parse_timepoint_ago(ago: &str) -> Result<SystemTime> {
|
||||
timepoint_ago(parse_duration(ago)?)
|
||||
@@ -155,3 +169,29 @@ pub fn is_within_bounds(
|
||||
| TimeDirection::After => item_time >= time_boundary,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::time::Duration;
|
||||
|
||||
use super::{add_millis, linear_backoff};
|
||||
|
||||
#[test]
|
||||
fn linear_backoff_scales_and_caps() {
|
||||
let base = Duration::from_secs(10);
|
||||
let limit = Duration::from_secs(25);
|
||||
|
||||
assert_eq!(linear_backoff(base, limit, 0), Duration::ZERO);
|
||||
assert_eq!(linear_backoff(base, limit, 1), Duration::from_secs(10));
|
||||
assert_eq!(linear_backoff(base, limit, 2), Duration::from_secs(20));
|
||||
assert_eq!(linear_backoff(base, limit, 3), limit);
|
||||
assert_eq!(linear_backoff(base, limit, u32::MAX), limit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn millis_deadline_saturates() {
|
||||
assert_eq!(add_millis(10, Duration::from_millis(20)), 30);
|
||||
assert_eq!(add_millis(u64::MAX, Duration::from_millis(1)), u64::MAX);
|
||||
assert_eq!(add_millis(0, Duration::from_secs(u64::MAX)), u64::MAX);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user