retry

package module
Version: v2.0.1+incompatible Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2017 License: MIT Imports: 8 Imported by: 0

README

gentleman-retry Build Status GoDoc Coverage Status Go Report Card

gentleman's v2 plugin providing retry policy capabilities to your HTTP clients.

Constant backoff strategy will be used by default with a maximum of 3 attempts, but you use a custom or third-party retry strategies. Request bodies will be cached in the stack in order to re-send them if needed.

By default, retry will happen in case of network error or server response error (>= 500 || = 429). You can use a custom Evaluator function to determine with custom logic when should retry or not.

Behind the scenes it implements a custom http.RoundTripper interface which acts like a proxy to http.Transport, in order to take full control of the response and retry the request if needed.

Installation

go get -u gopkg.in/h2non/gentleman-retry.v2

Versions

  • v1 - First version, uses gentleman@v1.
  • v2 - Latest version, uses gentleman@v2.

API

See godoc reference for detailed API documentation.

Examples

Default retry strategy
package main

import (
  "fmt"

  "gopkg.in/h2non/gentleman.v2"
  "gopkg.in/h2non/gentleman-retry.v2"
)

func main() {
  // Create a new client
  cli := gentleman.New()

  // Define base URL
  cli.URL("http://httpbin.org")

  // Register the retry plugin, using the built-in constant back off strategy
  cli.Use(retry.New(retry.ConstantBackoff))

  // Create a new request based on the current client
  req := cli.Request()

  // Define the URL path at request level
  req.Path("/status/503")

  // Set a new header field
  req.SetHeader("Client", "gentleman")

  // Perform the request
  res, err := req.Send()
  if err != nil {
    fmt.Printf("Request error: %s\n", err)
    return
  }
  if !res.Ok {
    fmt.Printf("Invalid server response: %d\n", res.StatusCode)
    return
  }
}
Exponential retry strategy

I would recommend you using go-resiliency package for custom retry estrategies:

go get -u gopkg.in/eapache/go-resiliency.v1/retrier
package main

import (
  "fmt"
  "time"

  "gopkg.in/h2non/gentleman.v2"
  "gopkg.in/h2non/gentleman-retry.v2"
  "gopkg.in/eapache/go-resiliency.v1/retrier"

)

func main() {
  // Create a new client
  cli := gentleman.New()

  // Define base URL
  cli.URL("http://httpbin.org")

  // Register the retry plugin, using a custom exponential retry strategy
  cli.Use(retry.New(retrier.New(retrier.ExponentialBackoff(3, 100*time.Millisecond), nil)))

  // Create a new request based on the current client
  req := cli.Request()

  // Define the URL path at request level
  req.Path("/status/503")

  // Set a new header field
  req.SetHeader("Client", "gentleman")

  // Perform the request
  res, err := req.Send()
  if err != nil {
    fmt.Printf("Request error: %s\n", err)
    return
  }
  if !res.Ok {
    fmt.Printf("Invalid server response: %d\n", res.StatusCode)
    return
  }
}

License

MIT - Tomas Aparicio

Documentation

Index

Constants

View Source
const (
	// RetryTimes defines the default max amount of times to retry a request.
	RetryTimes = 3

	// RetryWait defines the default amount of time to wait before each retry attempt.
	RetryWait = 100 * time.Millisecond
)
View Source
const Version = "2.0.1"

Version defines the package semantic version

Variables

View Source
var (
	// ConstantBackoff provides a built-in retry strategy based on constant back off.
	ConstantBackoff = retry.New(retry.ConstantBackoff(RetryTimes, RetryWait), nil)

	// ExponentialBackoff provides a built-int retry strategy based on exponential back off.
	ExponentialBackoff = retry.New(retry.ExponentialBackoff(RetryTimes, RetryWait), nil)
)
View Source
var (
	// ErrServer stores the error when a server error happens.
	ErrServer = errors.New("retry: server response error")
)
View Source
var Evaluator = func(err error, res *http.Response, req *http.Request) error {
	if err != nil {
		return err
	}
	if res.StatusCode >= 500 || res.StatusCode == 429 {
		return ErrServer
	}
	return nil
}

Evaluator determines when a request failed in order to retry it, evaluating the error, response and optionally the original request.

By default if will retry if an error is present or response status code is >= 500.

You can override this function to use a custom evaluator function with additional logic.

Functions

func InterceptTransport

func InterceptTransport(ctx *context.Context, retrier Retrier) error

InterceptTransport is a middleware function handler that intercepts the HTTP transport based on the given HTTP retrier and context.

func New

func New(retrier Retrier) plugin.Plugin

New creates a new retry plugin based on the given retry strategy.

Types

type EvalFunc

type EvalFunc func(error, *http.Response, *http.Request) error

EvalFunc represents the function interface for failed request evaluator.

type Retrier

type Retrier interface {
	Run(func() error) error
}

Retrier defines the required interface implemented by retry strategies.

type Transport

type Transport struct {
	// contains filtered or unexported fields
}

Transport provides a http.RoundTripper compatible transport who encapsulates the original http.Transport and provides transparent retry support.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements the required method by http.RoundTripper interface. Performs the network transport over the original http.Transport but providing retry support.

Jump to

Keyboard shortcuts

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