From c05ead912ede97100f795f55f206eaeb8add7231 Mon Sep 17 00:00:00 2001 From: timedout Date: Fri, 28 Aug 2026 16:38:22 +0100 Subject: [PATCH] fix: Don't increment backoff if we're still in backoff --- src/service/rooms/event_handler/mod.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 692cec626..101e9db87 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -44,7 +44,7 @@ pub struct Service { pub mutex_federation: RoomMutexMap, pub federation_handletime: SyncRwLock, pub extremity_squashers: SyncRwLock>>, - pub failed_pdu_pulls: SyncRwLock>, + failed_pdu_pulls: SyncRwLock>, joining_rooms: SyncRwLock>>, services: Services, server_shutdown: Notify, @@ -149,9 +149,7 @@ pub(super) fn ensure_can_pull_event(&self, event_id: &EventId) -> Result<()> { let Some((retry_count, last_retry)) = map.get(event_id) else { return Ok(()); }; - 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); - let next_retry = min.saturating_mul(*retry_count).min(max); + let next_retry = calc_next_retry(&self.services.server.config, *retry_count); if last_retry.elapsed() >= next_retry { Ok(()) } else { @@ -168,11 +166,13 @@ pub(super) fn ensure_can_pull_event(&self, event_id: &EventId) -> Result<()> { /// Marks a PDU as having a failed pull attempt, preventing it from being /// immediately re-fetched without a short cooldown. pub(super) fn hit_failed_pdu_pull(&self, event_id: OwnedEventId) { - let now = Instant::now(); let mut map = self.failed_pdu_pulls.write(); map.entry(event_id) .and_modify(|(retries, last_retry)| { - if *last_retry > now { + let next_retry = calc_next_retry(&self.services.server.config, *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 concurrently. return; } *retries = retries.saturating_add(1); @@ -200,3 +200,9 @@ fn get_room_version_rules(create_event: &Pdu) -> Result 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) +}