retry

package module
v0.0.0-...-939feaf Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2019 License: MIT Imports: 8 Imported by: 1

README

♻️ retry

Functional mechanism based on channels to perform actions repetitively until successful.

Awesome Patreon Build Status Code Coverage Code Quality GoDoc Research License

Usage

Quick start
var (
	response *http.Response
	action   retry.Action = func(_ uint) error {
		var err error
		response, err = http.Get("https://github.com/kamilsk/retry")
		return err
	}
)

if err := retry.Retry(retry.WithTimeout(time.Minute), action, strategy.Limit(10)); err != nil {
	// handle error
	return
}
// work with response
Console tool for command execution with retries

This example shows how to repeat console command until successful.

$ retry --infinite -timeout 10m -backoff=lin:500ms -- /bin/sh -c 'echo "trying..."; exit $((1 + RANDOM % 10 > 5))'

asciicast

See more details here.

Create HTTP client with retry

This example shows how to extend standard http.Client with retry under the hood.

type client struct {
	base       *http.Client
	strategies []strategy.Strategy
}

func New(timeout time.Duration, strategies ...strategy.Strategy) *client {
	return &client{
		base:       &http.Client{Timeout: timeout},
		strategies: strategies,
	}
}

func (c *client) Get(deadline <-chan struct{}, url string) (*http.Response, error) {
	var response *http.Response
	err := retry.Retry(deadline, func(uint) error {
		resp, err := c.base.Get(url)
		if err != nil {
			return err
		}
		response = resp
		return nil
	}, c.strategies...)
	return response, err
}
Control database connection

This example shows how to use retry to restore database connection by database/sql/driver.Pinger.

MustOpen := func() *sql.DB {
	db, err := sql.Open("stub", "stub://test")
	if err != nil {
		panic(err)
	}
	return db
}

go func(db *sql.DB, ctx context.Context, shutdown chan<- struct{}, frequency time.Duration,
	strategies ...strategy.Strategy) {

	defer func() {
		if r := recover(); r != nil {
			shutdown <- struct{}{}
		}
	}()

	ping := func(uint) error {
		return db.Ping()
	}

	for {
		if err := retry.Retry(ctx.Done(), ping, strategies...); err != nil {
			panic(err)
		}
		time.Sleep(frequency)
	}
}(MustOpen(), context.Background(), shutdown, time.Millisecond, strategy.Limit(1))
Use context for cancellation

This example shows how to use context and retry together.

communication := make(chan error)

go service.Listen(communication)

action := func(uint) error {
	communication <- nil   // ping
	return <-communication // pong
}
ctx := retry.WithContext(context.Background(), retry.WithTimeout(time.Second))
if err := retry.Retry(ctx.Done(), action, strategy.Delay(time.Millisecond)); err != nil {
	// the service does not respond within one second
}
Interrupt execution
interrupter := retry.Multiplex(
	retry.WithTimeout(time.Second),
	retry.WithSignal(os.Interrupt),
)
if err := retry.Retry(interrupter, func(uint) error { time.Sleep(time.Second); return nil }); err == nil {
	panic("press Ctrl+C")
}
// successful interruption

Installation

$ go get github.com/kamilsk/retry
$ # or use mirror
$ egg bitbucket.org/kamilsk/retry

egg1 is an extended go get.

Update

This library is using SemVer for versioning, and it is not BC-safe. Therefore, do not use go get -u to update it, use dep, glide or something similar for this purpose.

1 The project is still in prototyping.


Gitter

made with ❤️ by OctoLab

Documentation

Overview

Package retry provides functional mechanism based on channels to perform actions repetitively until successful.

This package is an extended version of https://godoc.org/github.com/Rican7/retry. Copyright © 2016 Trevor N. Suarez (Rican7)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsRecovered

func IsRecovered(err error) (interface{}, bool)

IsRecovered checks that the error is related to unhandled Action's panic and returns an original cause of panic.

func IsTimeout

func IsTimeout(err error) bool

IsTimeout checks that the error is related to the incident deadline on Retry call.

func Multiplex

func Multiplex(channels ...<-chan struct{}) <-chan struct{}

Multiplex combines multiple empty struct channels into one. TODO can be leaky, https://github.com/kamilsk/retry/issues/109

func Retry

func Retry(deadline <-chan struct{}, action Action, strategies ...strategy.Strategy) error

Retry takes an action and performs it, repetitively, until successful.

Optionally, strategies may be passed that assess whether or not an attempt should be made.

func WithContext

func WithContext(parent context.Context, deadline <-chan struct{}) context.Context

WithContext returns Context with cancellation based on empty struct channel.

func WithDeadline

func WithDeadline(deadline time.Time) <-chan struct{}

WithDeadline returns empty struct channel above on `time.Timer` channel. TODO can be leaky, https://github.com/kamilsk/retry/issues/109

func WithSignal

func WithSignal(s os.Signal) <-chan struct{}

WithSignal returns empty struct channel above on `os.Signal` channel. TODO can be leaky, https://github.com/kamilsk/retry/issues/109

func WithTimeout

func WithTimeout(timeout time.Duration) <-chan struct{}

WithTimeout returns empty struct channel above on `time.Timer` channel. TODO can be leaky, https://github.com/kamilsk/retry/issues/109

Types

type Action

type Action func(attempt uint) error

Action defines a callable function that package retry can handle.

Directories

Path Synopsis
Package backoff provides stateless methods of calculating durations based on a number of attempts made.
Package backoff provides stateless methods of calculating durations based on a number of attempts made.
Package classifier provides a way to classify an occurred error.
Package classifier provides a way to classify an occurred error.
cmd
examples module
Package jitter provides methods of transforming durations.
Package jitter provides methods of transforming durations.
sandbox module
Package strategy provides a way to change the way that retry is performed.
Package strategy provides a way to change the way that retry is performed.

Jump to

Keyboard shortcuts

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