Skip to content

mzattahri/backoff

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GoDoc reference Lint Test

Backoff

Package backoff implements backoff logic for retry loops using Go 1.23+ iterators.

Usage

Retries with Attempts()

Use Attempts() for bounded retries. The iterator sleeps the backoff duration after each iteration before yielding the next attempt:

for attempt := range backoff.Attempts(ctx, time.Second, 30*time.Second, backoff.Exponential(2), 5) {
    if err := doSomething(); err == nil {
        return nil
    }
    log.Printf("attempt %d failed", attempt)
    // Sleep happens automatically before next iteration
}
return errors.New("max retries exceeded")

With Timeout

Use context.WithTimeout to limit total elapsed time:

ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()

for attempt := range backoff.Attempts(ctx, time.Second, 30*time.Second, backoff.Exponential(2), 10) {
    if err := doSomething(); err == nil {
        return nil
    }
}
return ctx.Err() // context.DeadlineExceeded after 2 minutes

With Jitter

Jitter is useful in distributed systems to avoid thundering herd problems:

for attempt := range backoff.Attempts(ctx, time.Second, 30*time.Second, backoff.Jitter(backoff.Exponential(2), 0.5), 5) {
    if err := doSomething(); err == nil {
        return nil
    }
}

Manual Sleep with Delays()

Use Delays() when you need control over the sleep. Unlike Attempts(), this iterator does not sleep—it yields the delay value for you to handle:

for attempt, delay := range backoff.Delays(ctx, time.Second, 30*time.Second, backoff.Exponential(2)) {
    if err := doSomething(); err == nil {
        return nil
    }
    log.Printf("attempt %d failed, retrying in %v", attempt, delay)
    time.Sleep(delay)
}
// Yields: (1, 1s), (2, 2s), (3, 4s), (4, 8s), (5, 16s), (6, 30s), ...

Step Functions

Function Description
Fixed() Always returns base (equivalent to Linear(0))
Linear(d) Adds d each iteration: base, base+d, base+2d, ...
Incremental(m) Multiplies base by count: base, base*m, base*2m, ...
Exponential(f) Exponential growth: base, base*f, base*f^2, ...
Jitter(fn, factor) Wraps any step function with randomized jitter in [d-factor*d, d]

Contributions

Contributions are welcome via Pull Requests.

About

Simple backoff duration generator in Go.

Topics

Resources

License

Stars

Watchers

Forks