deep-rent/retry

Logo

This library provides a retry mechanism for Go based on highly configurable backoff strategies. Unlike similar libraries, the retry mechanism is initiated through a reusable struct type, which allows for easy mocking and sharing of backoff configuration.

Test Status Documentation Code Quality

Installation

Download the libary using go get:

go get github.com/deep-rent/[email protected]

Add the following imports to your project:

import (
    "github.com/deep-rent/retry"
    "github.com/deep-rent/retry/backoff"
)

Usage

First, define a function to be retried. The signature must match retry.Attempt.

attempt := func(n int) error {
    if n == 5 {
        // succeed after 5 attempts
        return nil
    } else {
        // force retry
        return errors.New("whoops")
    }
}

Next, configure a retry.Cycler. Once configured, the cycler can be reused across your project.

// exponentially increase delays between consecutive attempts
cycler := retry.NewCycler(backoff.Exponential(5 * time.Second, 1.5))
cycler.Cap(3 * time.Minute)      // cap backoff to 3 minutes
cycler.Limit(25)                 // stop after 25 attempts
cycler.Timeout(10 * time.Minute) // time out after 10 minutes
cycler.Jitter(0.5)               // introduce 50% random jitter

Register a retry.ErrorHandler to catch intermediate errors.

cycler.OnError(func(n int, delay time.Duration, err error) {
    s := delay.Seconds()
    fmt.Printf("attempt #%d failed: %v => wait %4.f s\n", n, err, s)
})

Finally, retry attempt according to the previous configuration.

err := cycler.Try(attempt)
if err != nil {
    fmt.Printf("failed after retries: %v", err)
}

License

Licensed under the Apache 2.0 License. For the full copyright and licensing information, please view the LICENSE file that was distributed with this source code.

GitHub

View Github