retry

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2021 License: MIT Imports: 1 Imported by: 80

README

retry

Build Status Coverage Status Go Report Card Go Reference Latest Stable Version

A simple, stateless, functional mechanism to perform actions repetitively until successful.

Project Status

This project is currently in "pre-release". While the code is heavily tested, the API may change. Use a tagged version or vendor this dependency if you plan on using it.

That said, this code has been used in production without issue for years, and has been used by some relatively high-profile projects/codebases.

Examples

Basic
retry.Retry(func(attempt uint) error {
	return nil // Do something that may or may not cause an error
})
File Open
const logFilePath = "/var/log/myapp.log"

var logFile *os.File

err := retry.Retry(func(attempt uint) error {
	var err error

	logFile, err = os.Open(logFilePath)

	return err
})

if err != nil {
	log.Fatalf("Unable to open file %q with error %q", logFilePath, err)
}

logFile.Chdir() // Do something with the file
HTTP request with strategies and backoff
var response *http.Response

action := func(attempt uint) error {
	var err error

	response, err = http.Get("https://api.github.com/repos/Rican7/retry")

	if err == nil && response != nil && response.StatusCode > 200 {
		err = fmt.Errorf("failed to fetch (attempt #%d) with status code: %d", attempt, response.StatusCode)
	}

	return err
}

err := retry.Retry(
	action,
	strategy.Limit(5),
	strategy.Backoff(backoff.Fibonacci(10*time.Millisecond)),
)

if err != nil {
	log.Fatalf("Failed to fetch repository with error %q", err)
}
Retry with backoff jitter
action := func(attempt uint) error {
	return errors.New("something happened")
}

seed := time.Now().UnixNano()
random := rand.New(rand.NewSource(seed))

retry.Retry(
	action,
	strategy.Limit(5),
	strategy.BackoffWithJitter(
		backoff.BinaryExponential(10*time.Millisecond),
		jitter.Deviation(random, 0.5),
	),
)

Documentation

Overview

Package retry provides a simple, stateless, functional mechanism to perform actions repetitively until successful.

Copyright © 2016 Trevor N. Suarez (Rican7)

Example
package main

import (
	"github.com/Rican7/retry"
)

func main() {
	retry.Retry(func(attempt uint) error {
		return nil // Do something that may or may not cause an error
	})
}
Output:

Example (FileOpen)
package main

import (
	"log"
	"os"

	"github.com/Rican7/retry"
)

func main() {
	const logFilePath = "/var/log/myapp.log"

	var logFile *os.File

	err := retry.Retry(func(attempt uint) error {
		var err error

		logFile, err = os.Open(logFilePath)

		return err
	})

	if err != nil {
		log.Fatalf("Unable to open file %q with error %q", logFilePath, err)
	}

	logFile.Chdir() // Do something with the file
}
Output:

Example (HttpGetWithStrategies)
package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/Rican7/retry"
	"github.com/Rican7/retry/backoff"
	"github.com/Rican7/retry/strategy"
)

func main() {
	var response *http.Response

	action := func(attempt uint) error {
		var err error

		response, err = http.Get("https://api.github.com/repos/Rican7/retry")

		if err == nil && response != nil && response.StatusCode > 200 {
			err = fmt.Errorf("failed to fetch (attempt #%d) with status code: %d", attempt, response.StatusCode)
		}

		return err
	}

	err := retry.Retry(
		action,
		strategy.Limit(5),
		strategy.Backoff(backoff.Fibonacci(10*time.Millisecond)),
	)

	if err != nil {
		log.Fatalf("Failed to fetch repository with error %q", err)
	}
}
Output:

Example (WithBackoffJitter)
package main

import (
	"errors"
	"fmt"
	"math/rand"
	"time"

	"github.com/Rican7/retry"
	"github.com/Rican7/retry/backoff"
	"github.com/Rican7/retry/jitter"
	"github.com/Rican7/retry/strategy"
)

func main() {
	action := func(attempt uint) error {
		fmt.Println("attempt", attempt)

		return errors.New("something happened")
	}

	seed := time.Now().UnixNano()
	random := rand.New(rand.NewSource(seed))

	retry.Retry(
		action,
		strategy.Limit(5),
		strategy.BackoffWithJitter(
			backoff.BinaryExponential(10*time.Millisecond),
			jitter.Deviation(random, 0.5),
		),
	)

}
Output:

attempt 1
attempt 2
attempt 3
attempt 4
attempt 5

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Retry

func Retry(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.

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 jitter provides methods of transforming durations.
Package jitter provides methods of transforming durations.
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