Documentation
¶
Overview ¶
Package backoff implements backoff logic for loop controls.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Attempts ¶
func Attempts(ctx context.Context, base, ceiling time.Duration, fn StepFunc, maxAttempts int) iter.Seq[int]
Attempts returns an iterator that yields attempt numbers (1-based), sleeping the backoff duration after each iteration before yielding the next attempt. The sleep respects context cancellation. The iterator stops when the context is cancelled or maxAttempts is reached.
Example ¶
Example of using the package-level Attempts function.
for attempt := range backoff.Attempts(context.Background(), time.Millisecond, 10*time.Millisecond, backoff.Exponential(2), 5) {
fmt.Printf("attempt %d\n", attempt)
}
Output: attempt 1 attempt 2 attempt 3 attempt 4 attempt 5
func Delays ¶
func Delays(ctx context.Context, base, ceiling time.Duration, fn StepFunc) iter.Seq2[int, time.Duration]
Delays returns an infinite iterator that yields the 1-based attempt number and the delay duration. The caller is responsible for sleeping the returned duration. The iterator stops when the context is cancelled.
Example ¶
Example of using the package-level Delays function.
for attempt, delay := range backoff.Delays(context.Background(), time.Second, 30*time.Second, backoff.Exponential(2)) {
fmt.Printf("attempt %d, delay %v\n", attempt, delay)
if attempt == 3 {
break
}
}
Output: attempt 1, delay 1s attempt 2, delay 2s attempt 3, delay 4s
Types ¶
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator generates a sequence of duration values using a step function.
A Generator is not safe for concurrent use by multiple goroutines.
func New ¶
New returns a new generator that uses the given step function.
Base is the first value that will be returned, and the one from which the next values will be derived. Ceiling is the maximum value that can be generated. A ceiling of 0 disables the ceiling check.
func (*Generator) Attempts ¶
Attempts returns an iterator that yields attempt numbers (1-based), sleeping the backoff duration after each iteration before yielding the next attempt. The sleep respects context cancellation.
The iterator stops when the context is cancelled or maxAttempts is reached.
Example ¶
Example of using Attempts for automatic retries with sleep.
gen := backoff.New(time.Millisecond, 10*time.Millisecond, backoff.Exponential(2))
for attempt := range gen.Attempts(context.Background(), 5) {
fmt.Printf("attempt %d\n", attempt)
}
Output: attempt 1 attempt 2 attempt 3 attempt 4 attempt 5
func (*Generator) Delays ¶
Delays returns an infinite iterator that yields the 1-based attempt number and the delay duration. Unlike Generator.Attempts, this iterator does not sleep—the caller is responsible for sleeping the returned duration.
The iterator stops when the context is cancelled.
Example ¶
Example of using Generator.Delays for manual control over sleep.
gen := backoff.New(time.Second, 30*time.Second, backoff.Exponential(2))
for attempt, delay := range gen.Delays(context.Background()) {
fmt.Printf("attempt %d, delay %v\n", attempt, delay)
// caller controls when to sleep, e.g.: time.Sleep(delay)
if attempt == 3 {
break
}
}
Output: attempt 1, delay 1s attempt 2, delay 2s attempt 3, delay 4s
type StepFunc ¶
StepFunc is the signature of the function that generates step values for a Generator.
func Exponential ¶
Exponential returns an exponential step function.
Example ¶
Example of an exponential backoff.
gen := backoff.New(time.Second, 30*time.Second, backoff.Exponential(2))
var values []time.Duration
for _, d := range gen.Delays(context.Background()) {
values = append(values, d.Truncate(time.Second))
if len(values) == 10 {
break
}
}
fmt.Println(values)
Output: [1s 2s 4s 8s 16s 30s 30s 30s 30s 30s]
func Fixed ¶
func Fixed() StepFunc
Fixed returns a StepFunc that always returns the base duration. It is equivalent to Linear(0).
Example ¶
Example of a fixed backoff using the iterator API.
gen := backoff.New(time.Second, 10*time.Second, backoff.Fixed())
var values []time.Duration
for _, d := range gen.Delays(context.Background()) {
values = append(values, d)
if len(values) == 5 {
break
}
}
fmt.Println(values)
Output: [1s 1s 1s 1s 1s]
func Incremental ¶
Incremental returns a step function that scales the base by the given multiple each retry.
Example ¶
Example of an incremental backoff.
gen := backoff.New(time.Second, 10*time.Second, backoff.Incremental(2))
var values []time.Duration
for _, d := range gen.Delays(context.Background()) {
values = append(values, d)
if len(values) == 10 {
break
}
}
fmt.Println(values)
Output: [1s 2s 4s 6s 8s 10s 10s 10s 10s 10s]
func Jitter ¶
Jitter wraps a StepFunc and returns a new StepFunc that applies "full-range" jitter in the range [d - factor*d, d].
For example, with d=1s and factor=0.5, the result is uniformly distributed in [500ms, 1s]. Factor should be in [0, 1].
Example ¶
Jitter is particularly useful with distributed systems.
gen := backoff.New(time.Second, 30*time.Second, backoff.Jitter(backoff.Exponential(2), 0.5))
var values []time.Duration
for _, d := range gen.Delays(context.Background()) {
values = append(values, d.Truncate(time.Second))
if len(values) == 5 {
break
}
}
fmt.Println(values)
func Linear ¶
Linear returns a step function that adds d each retry.
Example ¶
Example of a linear backoff.
gen := backoff.New(time.Second, 10*time.Second, backoff.Linear(2*time.Second))
var values []time.Duration
for _, d := range gen.Delays(context.Background()) {
values = append(values, d)
if len(values) == 5 {
break
}
}
fmt.Println(values)
Output: [1s 3s 5s 7s 9s]