gotries

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2022 License: Apache-2.0 Imports: 7 Imported by: 2

README

Go Report Card LICENSE

gotries

A simple, flexible and production inspired golang retry library

Install
go get -u github.com/monime-lab/gotries
Sample
package main

import (
	"context"
	"errors"
	"github.com/monime-lab/gotries"
	"log"
)

func main() {
	//exampleOne()
	exampleTwo()
	//exampleThree()
	//customDefaultOptions()
}

func exampleOne() {
	err := gotries.Run(context.TODO(), func(state gotries.State) error {
		if state.CurrentAttempts() <= 2 {
			return errors.New("some error occurred")
		}
		log.Printf("Task completed")
		return nil
	})
	if err != nil {
		panic(err)
	}
}

func exampleTwo() {
	// the library is cancel or timeout aware on the Context during scheduling or on an error
	resp, err := gotries.Call(context.TODO(), func(state gotries.State) (interface{}, error) {
		if state.CurrentAttempts() == 6 {
			//return "It's a success!!!", nil
		}
		// if for_some_condition {
		// 	 state.StopNextAttempt(true)
		// }
		return nil, errors.New("something wen wrong")
	}, gotries.WithMaxAttempts(10))
	if err != nil {
		panic(err)
	}
	log.Printf("Response: %s", resp)
}

func exampleThree() {
	resp, err := gotries.Call(context.TODO(), // there is a 'Call2' also
		func(state gotries.State) (interface{}, error) {
			return getName(state.Context())
		},
		gotries.WithMaxAttempts(5),
		gotries.WithTaskName("getName"), // for debugging
		//gotries.WithBackoff(gotries.LinearBackoff),
		//gotries.WithBackoff(gotries.ConstantBackoff),
		//gotries.WithBackoff(gotries.FibonacciBackoff),
		gotries.WithBackoff(gotries.ExponentialBackoff),
		//gotries.WithBackoff(gotries.NewConstantBackoff(1*time.Second)),
		//gotries.WithBackoff(gotries.NewExponentialBackoff(gotries.ExponentialBackoffConfig{
		//	Multiplier: 2.0,
		//	Jitter:     0.2,
		//	BaseDelay:  500 * time.Millisecond,
		//	MaxDelay:   1 * time.Minute,
		//})),
		gotries.WithRecoverableErrorPredicate(func(err error) bool {
			// same as gotries.DefaultRecoverableErrorPredicate
			return !(errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded))
		}),
	)
	if err != nil {
		panic(err)
	}
	log.Printf("Response: %s", resp)
}

func getName(ctx context.Context) (string, error) {
	return "John Doe", nil
}

// func customDefaultOptions() {
//	gotries.SetDefaultOptions(
//		gotries.WithLogger(func(template string, args ...interface{}) {
//			zap.S().Infof(template, args...)
//		}),
//		gotries.WithBackoff(gotries.ConstantBackoff),
//	)
//}

Contribute

For issues, comments, recommendation or feedback please do it here.

Contributions are highly welcome.

👍

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ConstantBackoff = NewConstantBackoff(defaultBaseDelay)
)
View Source
var (
	DefaultRecoverableErrorPredicate = func(err error) bool {
		return !(errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded))
	}
)
View Source
var (
	ExponentialBackoff = NewExponentialBackoff(ExponentialBackoffConfig{
		Multiplier: 2.0,
		Jitter:     defaultJitterFactor,
		BaseDelay:  defaultBaseDelay,
		MaxDelay:   30 * time.Second,
	})
)
View Source
var (
	FibonacciBackoff = NewFibonacciBackoff2(FibonacciConfig{
		Delay:    defaultBaseDelay,
		MaxDelay: 30 * time.Second,
		Jitter:   defaultJitterFactor,
	})
)
View Source
var (
	LinearBackoff = NewLinearBackoff(defaultBaseDelay)
)

Functions

func Call

func Call(ctx context.Context, callable Callable, options ...Option) (interface{}, error)

Call is a syntactic sugar

func Call2

func Call2(ctx context.Context, callable2 Callable2, options ...Option) (interface{}, interface{}, error)

Call2 is a syntactic sugar

func Run

func Run(ctx context.Context, runnable Runnable, options ...Option) error

Run is a syntactic sugar

func SetDefaultOptions

func SetDefaultOptions(options ...Option)

Types

type Backoff

type Backoff interface {
	// NextDelay returns the amount of time to wait before the next
	// retry given the specified number of consecutive failures.
	NextDelay(failures int) time.Duration
}

Backoff defines the backoff abstraction, NB: Implementations must be safe for concurrent use

func NewConstantBackoff

func NewConstantBackoff(delay time.Duration) Backoff

NewConstantBackoff returns a Backoff that delays with the specified duration between failures

func NewConstantBackoff2

func NewConstantBackoff2(config ConstantBackoffConfig) Backoff

NewConstantBackoff2 returns a Backoff that delays with a linear pattern between failures

func NewExponentialBackoff

func NewExponentialBackoff(config ExponentialBackoffConfig) Backoff

NewExponentialBackoff returns a Backoff that delays with an exponential pattern between failures

func NewFibonacciBackoff2

func NewFibonacciBackoff2(config FibonacciConfig) Backoff

NewFibonacciBackoff2 returns a Backoff that returns FibonacciBackoff sequenced wait delays between failures

func NewLinearBackoff

func NewLinearBackoff(baseDelay time.Duration) Backoff

NewLinearBackoff returns a Backoff that delays with a linear pattern between failures

func NewLinearBackoff2

func NewLinearBackoff2(config LinearBackoffConfig) Backoff

NewLinearBackoff2 returns a Backoff that delays in a linear pattern between failures

type Callable

type Callable func(State) (interface{}, error)

type Callable2

type Callable2 func(State) (interface{}, interface{}, error)

type Callback

type Callback func(interface{}, error)

type Callback2

type Callback2 func(interface{}, interface{}, error)

type Config

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

type ConstantBackoffConfig

type ConstantBackoffConfig struct {
	// Delay is the amount of time to backoff after every failure.
	Delay time.Duration
	// Jitter is the factor with which the delays are randomized.
	Jitter float64
}

type ExponentialBackoffConfig

type ExponentialBackoffConfig struct {
	// BaseDelay is the amount of time to backoff after the first failure.
	BaseDelay time.Duration
	// Multiplier is the factor with which to multiply backoff after a
	// failed retry. Should ideally be greater than 1.
	Multiplier float64
	// Jitter is the factor with which the delays are randomized.
	Jitter float64
	// MaxDelay is the upper bound of backoff delay.
	MaxDelay time.Duration
}

type FibonacciConfig

type FibonacciConfig struct {
	// Delay is the amount of time to backoff after every failure.
	Delay time.Duration
	// Jitter is the factor with which the delays are randomized.
	Jitter float64
	// MaxDelay is the upper bound of backoff delay.
	MaxDelay time.Duration
}

type LinearBackoffConfig

type LinearBackoffConfig struct {
	// BaseDelay is the amount of time to backoff after every failure.
	BaseDelay time.Duration
	// MaxDelay is the upper bound of backoff delay.
	MaxDelay time.Duration
	// Jitter is the factor with which the delays are randomized.
	Jitter float64
}

type LoggerFunc

type LoggerFunc func(template string, args ...interface{})

type Option

type Option interface {
	Apply(c *Config)
}

func WithBackoff

func WithBackoff(backoff Backoff) Option

WithBackoff set the retry backoff algorithm to use. Default is LinearBackoff

func WithMaxAttempts

func WithMaxAttempts(attempts int) Option

WithMaxAttempts set the max retry attempts before giving up; < 0 means keep retrying "forever" Note, attempt semantics begins after the first execution. Default is 3

func WithRecoverableErrorPredicate

func WithRecoverableErrorPredicate(predicate func(err error) bool) Option

WithRecoverableErrorPredicate set the predicate use to test whether an error is recoverable or not before a retry is scheduled. The default ensures the error is neither context.Canceled nor context.DeadlineExceeded

func WithTaskName

func WithTaskName(name string) Option

WithTaskName name of the task useful for debugging...

type Retry

type Retry interface {
	Run(ctx context.Context, runnable Runnable) error
	Call(ctx context.Context, callable Callable) (interface{}, error)
	Call2(ctx context.Context, callable2 Callable2) (interface{}, interface{}, error)
}

func NewRetry

func NewRetry(options ...Option) Retry

type Runnable

type Runnable func(State) error

type State

type State interface {
	Retrying() bool
	LastError() error
	CurrentAttempts() int
	Context() context.Context
	StopNextAttempt(stop bool)
}

Directories

Path Synopsis
nolint
nolint

Jump to

Keyboard shortcuts

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