retry

package
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2022 License: Apache-2.0 Imports: 6 Imported by: 0

README

Retry

This packages attempts to provide an easy way to retry lambas.

It is implemented with the Exponential Backoff & Decorrelated Jitter Algorithm described here.

For usage examples please refer here

Documentation

Overview

Package retry please refer to README.md

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrAttemptsExceeded = errors.New("exceeded max attempts")

ErrAttemptsExceeded is returned when we exceeded the max attempts without succeeding

Functions

This section is empty.

Types

type Client

type Client struct {
	// MaxAttempts is the maximum number of retry attempts before giving up. (default: 3)
	MaxAttempts int

	// BaseDelay is the base amount of time between attempts (default: 10 ms)
	BaseDelay time.Duration

	// MaxDelay is the maximum possible delay (default: 1 second)
	MaxDelay time.Duration

	// CanRetry allows for selectively shortcutting the retries.
	// Useful for cases were retrying would never work. (default: retry always)
	CanRetry func(error) bool

	// IsIgnored allows for selectively ignoring some errors (from tracking) but still returning the error.
	// Useful for things like ignoring a HTTP404 when that is not an error
	IsIgnored func(error) bool

	// MetricsClient allows this package to emit metrics (default: no metrics)
	Metrics MetricsClient
}

Client implements the Exponential Backoff

func (*Client) Do

func (r *Client) Do(ctx context.Context, metricKey string, do func() error) error

Do executes the lambda until success, context is cancelled, attempts are exceeded or a fatal error.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/corsc/go-commons/resilience/retry"
)

func main() {
	// simplest usage; using the defaults
	ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancelFunc()

	err := (&retry.Client{}).Do(ctx, "myretry", func() error {
		// do something amazing here
		return nil
	})

	fmt.Printf("error was %v", err)
}
Output:

error was <nil>
Example (CustomErrorHandling)
package main

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"time"

	"github.com/corsc/go-commons/resilience/retry"
)

func main() {
	// some custom errors
	var ErrUserError = errors.New("bad user input - retrying won't help")
	var ErrNetworkError = errors.New("bad connection - retrying might help")

	ctx, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancelFunc()

	client := &retry.Client{
		CanRetry: func(err error) bool {
			if err == ErrUserError {
				return false
			}
			if err == ErrNetworkError {
				return true
			}
			return true
		},
	}

	err := client.Do(ctx, "myretry", func() error {
		resp, err := http.Get("http://www.google.com/")
		if err != nil {
			// pass HTTP client errors out
			return err
		}

		// convert response codes into errors (where appropriate)
		switch resp.StatusCode {
		case http.StatusOK:
			return nil

		case http.StatusBadRequest:
			return ErrUserError

		case http.StatusBadGateway:
			return ErrNetworkError
		}

		return nil
	})

	fmt.Printf("error was %v", err)
}
Output:

error was <nil>

type MetricsClient

type MetricsClient interface {
	Incr(key string, tags ...string)
	Duration(key string, start time.Time, tags ...string)
}

MetricsClient defines the metrics interface used by this package

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL