1
0
Fork 0
forked from 0x2E/fusion
fusion/service/pull/backoff.go
Michael Lynch df412f17d3
Recover after feed fetch failure with exponential backoff (#108)
* Recover after feed fetch failure with exponential backoff

The current implementation stops attempting to fetch a feed if fusion encounters any error fetching it. The only way to continue fetching the feed is if the user manually forces a refresh.

This allows fusion to recover from feed fetch errors by tracking the number of consecutive failures and slowing down requests for consistent failure. If a feed always fails, we eventually slow to only checking it once per week.

Fixes #67

* Add comment
2025-03-24 11:11:18 +08:00

31 lines
913 B
Go

package pull
import (
"math"
"time"
)
// maxBackoff is the maximum time to wait before checking a feed due to past
// errors.
const maxBackoff = 7 * 24 * time.Hour
// CalculateBackoffTime calculates the exponential backoff time based on the
// number of consecutive failures.
// The formula is: interval * (1.8 ^ consecutiveFailures), capped at maxBackoff.
func CalculateBackoffTime(consecutiveFailures uint) time.Duration {
// If no failures, no backoff needed
if consecutiveFailures == 0 {
return 0
}
intervalMinutes := float64(interval.Minutes())
backoffMinutes := intervalMinutes * math.Pow(1.8, float64(consecutiveFailures))
// floats go to Inf if the number is too large to represent in a float type,
// so check that it's not +/- Inf.
if math.IsInf(backoffMinutes, 0) || backoffMinutes > maxBackoff.Minutes() {
return maxBackoff
}
return time.Duration(backoffMinutes) * time.Minute
}