httpretry: github.com/ybbus/httpretry Index | Files

package httpretry

import "github.com/ybbus/httpretry"

Index

Package Files

backoff.go client.go option.go retry.go roundtripper.go

Variables

var (

    // ConstantBackoff waits for the exact same duration after a failed retry.
    //
    // constantWait: the constant backoff
    //
    // maxJitter: random interval [0, maxJitter) added to the exponential backoff
    //
    // Example:
    //   minWait = 2 * time.Seconds
    //   maxJitter = 0 * time.Seconds
    //
    //   Backoff will be: 2, 2, 2, ...
    ConstantBackoff = func(constantWait time.Duration, maxJitter time.Duration) BackoffPolicy {
        if constantWait < 0 {
            constantWait = 0
        }
        if maxJitter < 0 {
            maxJitter = 0
        }

        return func(attemptCount int) time.Duration {
            return constantWait + randJitter(maxJitter)
        }
    }

    // LinearBackoff increases the backoff time by multiplying the minWait duration by the number of attempts.
    //
    // minWait: the initial backoff
    //
    // maxWait: sets an upper bound on the maximum time to wait between two requests. set to 0 for no upper bound
    //
    // maxJitter: random interval [0, maxJitter) added to the linear backoff
    //
    // Example:
    //   minWait = 1 * time.Seconds
    //   maxWait = 5 * time.Seconds
    //   maxJitter = 0 * time.Seconds
    //
    //   Backoff will be: 1, 2, 3, 4, 5, 5, 5, ...
    LinearBackoff = func(minWait time.Duration, maxWait time.Duration, maxJitter time.Duration) BackoffPolicy {
        if minWait < 0 {
            minWait = 0
        }
        if maxJitter < 0 {
            maxJitter = 0
        }
        if maxWait < minWait {
            maxWait = 0
        }
        return func(attemptCount int) time.Duration {
            nextWait := time.Duration(attemptCount)*minWait + randJitter(maxJitter)
            if maxWait > 0 {
                return minDuration(nextWait, maxWait)
            }
            return nextWait
        }
    }

    // ExponentialBackoff increases the backoff exponentially by multiplying the minWait with 2^attemptCount
    //
    // minWait: the initial backoff
    //
    // maxWait: sets an upper bound on the maximum time to wait between two requests. set to 0 for no upper bound
    //
    // maxJitter: random interval [0, maxJitter) added to the exponential backoff
    //
    // Example:
    //   minWait = 1 * time.Seconds
    //   maxWait = 60 * time.Seconds
    //   maxJitter = 0 * time.Seconds
    //
    //   Backoff will be: 1, 2, 4, 8, 16, 32, 60, 60, ...
    ExponentialBackoff = func(minWait time.Duration, maxWait time.Duration, maxJitter time.Duration) BackoffPolicy {
        if minWait < 0 {
            minWait = 0
        }
        if maxJitter < 0 {
            maxJitter = 0
        }
        if maxWait < minWait {
            maxWait = 0
        }
        return func(attemptCount int) time.Duration {
            nextWait := time.Duration(math.Pow(2, float64(attemptCount-1)))*minWait + randJitter(maxJitter)
            if maxWait > 0 {
                return minDuration(nextWait, maxWait)
            }
            return nextWait
        }
    }
)

func GetOriginalRoundtripper Uses

func GetOriginalRoundtripper(client *http.Client) http.RoundTripper

GetOriginalRoundtripper returns the original roundtripper that was embedded in the retry roundtripper.

func GetOriginalTransport Uses

func GetOriginalTransport(client *http.Client) (*http.Transport, error)

GetOriginalTransport retrieves the original http.Transport that was mebedded in the retry roundtripper.

func ModifyOriginalTransport Uses

func ModifyOriginalTransport(client *http.Client, f func(transport *http.Transport)) error

ModifyOriginalTransport allows to modify the original http.Transport that was embedded in the retry roundtipper.

func NewCustomClient Uses

func NewCustomClient(client *http.Client, opts ...Option) *http.Client

NewCustomClient returns the provided http client with retry functionality wrapped around the Roundtripper (client.Transport).

You should not replace the client.Transport field after creating the retry client, otherwise you will lose the retry functionality.

If you need to change the original client.Transport field you may use the helper functions:

err := httpretry.ModifyTransport(retryClient, func(t *http.Transport){t.TLSHandshakeTimeout = 5 * time.Second})
if err != nil { ... } // will be nil if embedded Roundtripper was not of type http.Transport

func NewDefaultClient Uses

func NewDefaultClient(opts ...Option) *http.Client

NewDefaultClient returns a default http client with retry functionality wrapped around the Roundtripper (client.Transport).

You should not replace the client.Transport field, otherwise you will lose the retry functionality.

If you need to set / change the original client.Transport field you have two options:

1. create your own http client and use NewCustomClient() function to enrich the client with retry functionality.

client := &http.Client{}
client.Transport = &http.Transport{ ... }
retryClient := httpretry.NewCustomClient(client)

2. use one of the helper functions (e.g. httpretry.ModifyOriginalTransport(retryClient)) to retrieve and change the Transport.

retryClient := httpretry.NewDefaultClient()
err := httpretry.ModifyOriginalTransport(retryClient, func(t *http.Transport){t.TLSHandshakeTimeout = 5 * time.Second})
if err != nil { ... } // will be nil if embedded Roundtripper was not of type http.Transport

func ReplaceOriginalRoundtripper Uses

func ReplaceOriginalRoundtripper(client *http.Client, roundtripper http.RoundTripper) error

ReplaceOriginalRoundtripper replaces the original roundtripper that was embedded in the retry roundtripper

type BackoffPolicy Uses

type BackoffPolicy func(attemptCount int) time.Duration

BackoffPolicy is used to calculate the time to wait, before executing another request.

The backoff can be calculated by taking the current number of retries into consideration.

type Option Uses

type Option func(*RetryRoundtripper)

Option is a function type to modify the RetryRoundtripper configuration

func WithBackoffPolicy Uses

func WithBackoffPolicy(backoffPolicy BackoffPolicy) Option

WithBackoffPolicy sets the user defined backoff policy.

Default: ExponentialBackoff(1*time.Second, 30*time.Second, 200*time.Millisecond)

func WithMaxRetryCount Uses

func WithMaxRetryCount(maxRetryCount int) Option

WithMaxRetryCount sets the maximum number of retries if an http request was not successful.

Default: 5

func WithRetryPolicy Uses

func WithRetryPolicy(retryPolicy RetryPolicy) Option

WithRetryPolicy sets the user defined retry policy.

Default: RetryPolicy checks for some common errors that are likely not retryable and for status codes that should be retried.

For example:

- url parsing errors
- too many redirects
- certificate errors
- BadGateway
- ServiceUnavailable
- etc.

type RetryPolicy Uses

type RetryPolicy func(statusCode int, err error) bool

RetryPolicy decides if a request should be retried.

This is done by examining the response status code and the error message of the last response.

The statusCode may be 0 if there was no response available (e.g. in case of a request error).

type RetryRoundtripper Uses

type RetryRoundtripper struct {
    Next             http.RoundTripper
    MaxRetryCount    int
    ShouldRetry      RetryPolicy
    CalculateBackoff BackoffPolicy
}

RetryRoundtripper is the roundtripper that will wrap around the actual http.Transport roundtripper to enrich the http client with retry functionality.

func (*RetryRoundtripper) RoundTrip Uses

func (r *RetryRoundtripper) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements the actual roundtripper interface (http.RoundTripper).

Package httpretry imports 11 packages (graph). Updated 2020-02-16. Refresh now. Tools for package owners.