Fix retry body replay and jitter panic; drive delays via internal/clock
Gate the retry decision on body rewindability: an idempotent request whose body cannot be replayed (no GetBody) is now returned as-is instead of looping with an empty body or surfacing a stale, already-drained response. Guard ExponentialBackoff against rand.Int64N panicking when delay/2 rounds to zero. Use internal/clock for inter-attempt delays so retry timing is consistent with the rest of the codebase and testable without real sleeps.
This commit is contained in:
@@ -1,12 +1,17 @@
|
||||
package retry
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.codelab.vc/pkg/httpx/internal/clock"
|
||||
)
|
||||
|
||||
type options struct {
|
||||
maxAttempts int // default 3
|
||||
backoff Backoff // default ExponentialBackoff(100ms, 5s, true)
|
||||
policy Policy // default: defaultPolicy (retry on 5xx and network errors)
|
||||
retryAfter bool // default true, respect Retry-After header
|
||||
maxAttempts int // default 3
|
||||
backoff Backoff // default ExponentialBackoff(100ms, 5s, true)
|
||||
policy Policy // default: defaultPolicy (retry on 5xx and network errors)
|
||||
retryAfter bool // default true, respect Retry-After header
|
||||
clk clock.Clock // time source for backoff delays (real by default)
|
||||
}
|
||||
|
||||
// Option configures the retry transport.
|
||||
@@ -18,6 +23,17 @@ func defaults() options {
|
||||
backoff: ExponentialBackoff(100*time.Millisecond, 5*time.Second, true),
|
||||
policy: defaultPolicy{},
|
||||
retryAfter: true,
|
||||
clk: clock.System(),
|
||||
}
|
||||
}
|
||||
|
||||
// withClock sets the clock used for inter-attempt delays. Unexported; for
|
||||
// deterministic tests.
|
||||
func withClock(c clock.Clock) Option {
|
||||
return func(o *options) {
|
||||
if c != nil {
|
||||
o.clk = c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user