mirror of https://github.com/jpillora/backoff.git
Remove unnecessary Retry.Last method, and improve the documentation
This commit is contained in:
parent
a8722a14a5
commit
c58aede9a8
35
retry.go
35
retry.go
|
@ -4,12 +4,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Retry extends Backoff to provide a simpler, higher-level API, for
|
// Retry extends [Backoff] to provide a simpler, higher-level API, for
|
||||||
// implementing exponential backoff/retry logic.
|
// implementing exponential backoff/retry logic.
|
||||||
//
|
//
|
||||||
// It is not safe to use concurrently. Additionally, mutating the Backoff
|
// It is not safe to use concurrently.
|
||||||
// or Next fields directly may have unintended consequences, e.g. affecting the
|
|
||||||
// Last value.
|
|
||||||
type Retry struct {
|
type Retry struct {
|
||||||
// Backoff is the internal [Backoff].
|
// Backoff is the internal [Backoff].
|
||||||
Backoff *Backoff
|
Backoff *Backoff
|
||||||
|
@ -17,8 +15,7 @@ type Retry struct {
|
||||||
// Next is the next allowed time. As that suggests, it is set on
|
// Next is the next allowed time. As that suggests, it is set on
|
||||||
// [Retry.Allow], each time an attempt is allowed.
|
// [Retry.Allow], each time an attempt is allowed.
|
||||||
// Another attempt will be allowed if Next is a time <= now, or the zero
|
// Another attempt will be allowed if Next is a time <= now, or the zero
|
||||||
// value. Mutating this field directly may cause unexpected behavior,
|
// value.
|
||||||
// use [Retry.Reset], instead.
|
|
||||||
Next time.Time
|
Next time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +24,8 @@ var timeNow = time.Now // monkey patchable for testing
|
||||||
// Allow acts as a limiter, returning the next allowed time, or `time.Time{}`,
|
// Allow acts as a limiter, returning the next allowed time, or `time.Time{}`,
|
||||||
// if the next attempt should commence, inclusive of the first attempt.
|
// if the next attempt should commence, inclusive of the first attempt.
|
||||||
// If `time.Time{}` is returned, [Backoff.Duration] will be called, which will
|
// If `time.Time{}` is returned, [Backoff.Duration] will be called, which will
|
||||||
// increment the [Backoff.Attempt] count, and then used to update [Retry.Next].
|
// increment the [Backoff.Attempt] count. The value of [Retry.Next] will be
|
||||||
|
// updated to reflect the next allowed time (the returned duration, from now).
|
||||||
func (x *Retry) Allow() time.Time {
|
func (x *Retry) Allow() time.Time {
|
||||||
now := timeNow()
|
now := timeNow()
|
||||||
if x.Next != (time.Time{}) && now.Before(x.Next) {
|
if x.Next != (time.Time{}) && now.Before(x.Next) {
|
||||||
|
@ -37,20 +35,17 @@ func (x *Retry) Allow() time.Time {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets the attempt count, and clears the next allowed time, removing
|
// Reset resets the attempt count and clears the next allowed time, thereby
|
||||||
// any applied limit.
|
// removing any applied backoff delay. This method is typically invoked after
|
||||||
// This method will typically be called after each success.
|
// a successful operation. By doing so, it ensures that if a subsequent
|
||||||
|
// failure occurs, the backoff timer restarts from the minimum duration. This
|
||||||
|
// approach is useful for scenarios where intermittent issues are resolved,
|
||||||
|
// allowing the system to promptly react to new errors without being delayed
|
||||||
|
// by the increased backoff time accumulated from previous failures.
|
||||||
|
//
|
||||||
|
// Clearing the Next field directly is an alternative, that will allow the next
|
||||||
|
// attempt immediately, without resetting the attempt count.
|
||||||
func (x *Retry) Reset() {
|
func (x *Retry) Reset() {
|
||||||
x.Backoff.Reset()
|
x.Backoff.Reset()
|
||||||
x.Next = time.Time{}
|
x.Next = time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last is the last time Allow was called.
|
|
||||||
//
|
|
||||||
// WARNING: Mutating the Backoff directly may cause this value to be incorrect.
|
|
||||||
func (x *Retry) Last() time.Time {
|
|
||||||
if x.Next == (time.Time{}) {
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
return x.Next.Add(-x.Backoff.ForAttempt(x.Backoff.Attempt() - 1))
|
|
||||||
}
|
|
||||||
|
|
|
@ -122,7 +122,10 @@ func ExampleRetry_Allow_backoffBehavior() {
|
||||||
attemptAllowAt := func(at time.Duration) {
|
attemptAllowAt := func(at time.Duration) {
|
||||||
currentAttempt := retry.Backoff.Attempt() - 1
|
currentAttempt := retry.Backoff.Attempt() - 1
|
||||||
currentBackoff := retry.Backoff.ForAttempt(currentAttempt)
|
currentBackoff := retry.Backoff.ForAttempt(currentAttempt)
|
||||||
lastAttempt := retry.Last()
|
var lastAttempt time.Time
|
||||||
|
if retry.Next != (time.Time{}) {
|
||||||
|
lastAttempt = retry.Next.Add(-retry.Backoff.ForAttempt(retry.Backoff.Attempt() - 1))
|
||||||
|
}
|
||||||
now := time.Unix(0, int64(at))
|
now := time.Unix(0, int64(at))
|
||||||
timeNow = func() time.Time { return now }
|
timeNow = func() time.Time { return now }
|
||||||
limitedUntil := retry.Allow()
|
limitedUntil := retry.Allow()
|
||||||
|
|
Loading…
Reference in New Issue