feat(scrobble): add backoffDelay schedule (1m, 5m, 30m, 2h, 6h, give up)
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
package scrobble
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// backoffSchedule maps the failure count (1-indexed: 1 = first failure
|
||||||
|
// just happened) to the delay before the next attempt. Per spec §M4a:
|
||||||
|
// 1m → 5m → 30m → 2h → 6h, then give up.
|
||||||
|
var backoffSchedule = []time.Duration{
|
||||||
|
1 * time.Minute,
|
||||||
|
5 * time.Minute,
|
||||||
|
30 * time.Minute,
|
||||||
|
2 * time.Hour,
|
||||||
|
6 * time.Hour,
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxAttempts = 5
|
||||||
|
|
||||||
|
// backoffDelay returns the delay before the next attempt given the value
|
||||||
|
// of the `attempts` column AFTER the failure has been recorded (1-indexed:
|
||||||
|
// attempts=1 means the first failure just happened, the next retry should
|
||||||
|
// wait 1 minute). Returns (_, false) when attempts > maxAttempts (the
|
||||||
|
// caller should mark the row failed).
|
||||||
|
func backoffDelay(attempts int) (time.Duration, bool) {
|
||||||
|
if attempts < 1 || attempts > maxAttempts {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return backoffSchedule[attempts-1], true
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package scrobble
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBackoffDelay(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
attempts int
|
||||||
|
want time.Duration
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{1, 1 * time.Minute, true},
|
||||||
|
{2, 5 * time.Minute, true},
|
||||||
|
{3, 30 * time.Minute, true},
|
||||||
|
{4, 2 * time.Hour, true},
|
||||||
|
{5, 6 * time.Hour, true},
|
||||||
|
{6, 0, false},
|
||||||
|
{99, 0, false},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
got, ok := backoffDelay(c.attempts)
|
||||||
|
if ok != c.ok {
|
||||||
|
t.Errorf("backoffDelay(%d) ok = %v, want %v", c.attempts, ok, c.ok)
|
||||||
|
}
|
||||||
|
if got != c.want {
|
||||||
|
t.Errorf("backoffDelay(%d) = %v, want %v", c.attempts, got, c.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user