Giter Club home page Giter Club logo

retry's Introduction

retry Tweet

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

Awesome Patreon Build Status Go Report Card Coverage Status GoDoc License

Differences from Rican7/retry

  • Fixed bug with an unexpected infinite loop.
    • Added a clear mechanism for this purpose as the Infinite strategy.
  • Added support of cancellation (based on simple channel, e.g. context.Done).
    • Made honest Action execution.
  • Added error transmission between attempts.
    • Added classifier to handle them (see classifier package).
  • Added CLI tool retry which provides functionality for repeating terminal commands (see cmd/retry).

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
}

See more details here.

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

Mirror

$ egg bitbucket.org/kamilsk/retry

egg 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 or something similar for this purpose.

Notes

  • research
  • tested on Go 1.5, 1.6, 1.7, 1.8, 1.9 and 1.10

Gitter @kamilsk @octolab

made with ❤️ by OctoLab

retry's People

Contributors

kamilsk avatar rican7 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.