goretry

package module
v0.0.0-...-766361f Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2022 License: MIT Imports: 4 Imported by: 0

README

Go Retry

Go Reference build_pr Go Report Card Built with WeBuild

Go Retry is Go language library that enables the code can retry to do it if it's failed.

It's good to handle transient failures when it tries to connect to a service or network resource, or try to do a required logic.

Go Retry library supports multiple strategies:

Quick starts

  1. Download dependencies:
go get -u github.com/vnteamopen/goretry
  1. Import and usage:
package main

import (
	"fmt"
	"github.com/vnteamopen/goretry"
)

func main() {
	counter := 0
	goretry.Do(10*time.Millisecond, func() error {
		if counter == 5 {
			fmt.Println("Success")
			return nil
		}
		fmt.Println("Fail")
		counter++
		return fmt.Errorf("fake error")
	})
}

Features

Custom instance

All functions from goretry such as goretry.Do(), goretry.Fibonacci() uses default configuration instance. You can custom configuration of goretry with changes:

package main

import (
	"fmt"
	"github.com/vnteamopen/goretry"
)

func main() {
	customRetry := Instance{
		MaxStopRetries: 10, // maximum number of retry times. Default: NoLimit.
		MaxStopTotalWaiting: time.Duration(5 * time.Minute), // maximum total waiting duration of retry times. Default: NoLimit
		CeilingSleep: time.Duration(1 * time.Minute), // maximum duration waiting that can increase to.
		Logger: os.Stdout, // Logger defines log output, main purpose for debug
	}
	customRetry.Do(10*time.Millisecond, func() error {
		// Do something here
	})
}
Constant Backoff

Simplest case of retry strategy, it keep constant waiting duration beetween retry actions.

Constant backoff retry adds a fixed waiting duration after the first failure and between retry actions with the following formula:

duration(t) = <constant value>

constant backoff

package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	goretry.Do(5*time.Second, func() error {
		// Do something here
	})
}
Linear Backoff

The linear backoff retry strategy supports the waiting duration after the first failure and increases the waiting duration of the next retries. It increases constantly delta x from the previous waiting time with the formula:

duration(t) = duration(t-1) + x

Linear backoff

package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	firstWaiting := 1*time.Second
	increasement := 1*time.Second
	goretry.Linear(firstWaiting, increasement, func() error {
		// Do something here
	})
}
Fibonacci Backoff

The Fibonacci backoff retry strategy supports the waiting duration that calculates by using the Fibonacci sequence with the formula:

duration(t) = duration(t-1) + duration(t-2)

Fibonacci backoff

package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	initWaiting := 1*time.Second
	goretry.Fibonacci(initWaiting, func() error {
		// Do something here
	})
}
Quadratic Backoff

The quadratic backoff retry strategy supports the waiting duration that calculates by following the quadratic curve with the formula:

duration(t) = attempt ^ 2 * base-time

Quadratic Backoff

package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	baseDuration := time.Second
	goretry.Quadratic(baseDuration, func() error {
		// Do something here
	})
}
Exponential Backoff

The exponential backoff retry strategy supports the waiting duration that calculates by following the exponential curve with the formula:

duration(t) = 2 ^ attempt * base-time

Exponential Backoff

package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	baseDuration := time.Second
	goretry.Exponential(baseDuration, func() error {
		// Do something here
	})
}
Polynomial Backoff

The Polynomial backoff retry strategy supports the waiting duration that calculates by following the formula:

duration(t) = attempt ^ degree * base-time

Polynomial Backoff

package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	baseDuration := time.Second
	degree := 3
	goretry.Polynomial(baseDuration, degree, func() error {
		// Do something here
	})
}
Jitter

Suppose we have multiple retry callers do an action or send requests that collide and fail. They all decide to retry with a backoff strategy. They will all retry at the same time, which leads to colliding again.

Jitter is a technique to solve that problem. It adds or removes different random waiting durations to back off time. So each next retry will happen at a different time and help to avoid several calls next time.

Jitter



package main

import (
	"github.com/vnteamopen/goretry"
)

func main() {
	customRetry := Instance{
		JitterEnabled: true,                     // Enable Jitter
		JitterFloorSleep: 10 * time.Millisecond, // Minimun waiting duration after jitter is 10ms
	}
	customRetry.Do(...)
	customRetry.Fibonacci(...)
}

Documentation

Index

Constants

View Source
const (
	NoLimit    = int64(0)
	NoDuration = time.Duration(0)
)

Variables

This section is empty.

Functions

func Do

func Do(backoff time.Duration, action func() error)

Do is basic retry function. If action return error, it will retry after constant backoff duration. If backoff = 0, no waiting duration between action retries, same with NoBackoff().

func Exponential

func Exponential(baseTime time.Duration, action func() error)
Exponential performs retry function with backoff time calculated by exponential function.

It will wait for baseTime to do the first retry, and then increase the waiting time by time = 2 ^ attempt * baseTime

func Fibonacci

func Fibonacci(startWaiting time.Duration, action func() error)
Fibonacci performs retry function with the waiting duration calculated using Fibonacci sequence.

It will wait for firstWaiting to do the first retry

func Linear

func Linear(backoff, incrementStep time.Duration, action func() error)
Linear performs retry function with linearly incremental backoff time.

It will wait for firstWaiting to do the first retry, and then increase the waiting time by incrementStep for each next retry

func NoBackoff

func NoBackoff(action func() error)

NoBackoff is a shortcut to call Do(0, action). It will retry immediately and don't wait at all.

func Polynomial

func Polynomial(baseTime time.Duration, degree int64, action func() error)
Polynomial performs retry function with backoff time calculated by Polynomial function.

It will wait for baseTime to do the first retry, and then increase the waiting time by time = attempt ^ degree * baseTime

func Quadratic

func Quadratic(baseTime time.Duration, action func() error)
Quadratic performs retry function with backoff time calculated by quadratic function.

It will wait for baseTime to do the first retry, and then increase the waiting time by time = attempt ^ 2 * baseTime

Types

type Instance

type Instance struct {
	// MaxStopRetries defines maximum number of retry times. If reach to this number, the retry will be stopped. Default: NoLimit.
	MaxStopRetries int64

	// MaxStopDuration defines maximum total waiting duration of retry times. If total number of waiting duration is reached, the try will be stopped. Default: NoLimit.
	MaxStopTotalWaiting time.Duration

	// CeilingSleep defines max duration waiting duration during increasing. If next increasing is over this value, it keeps this value instead. Default: NoLimit.
	CeilingSleep time.Duration

	// JitterEnabled defines if Jitter is applied when calculating sleep time. Jitter adds or removes different random waiting durations to back off time. Default: false
	JitterEnabled bool

	// JitterFloorSleep is the lower bound of the random function when calculating sleep time with jitter. Default: NoLimit
	JitterFloorSleep time.Duration

	// Logger defines log output. You can use os.Stdout, file or any writer stream.
	Logger io.Writer
}

Instance defines a goretry instance with their configs.

func (*Instance) Do

func (i *Instance) Do(backoff time.Duration, action func() error)

Do is basic retry function. If action return error, it will retry after constant backoff duration. If backoff = 0, no waiting duration between action retries, same with NoBackoff().

func (*Instance) Exponential

func (i *Instance) Exponential(baseTime time.Duration, action func() error)
Exponential performs retry function with backoff time calculated by exponential function.

It will wait for baseTime to do the first retry, and then increase the waiting time by time = 2 ^ attempt * baseTime

func (*Instance) Fibonacci

func (i *Instance) Fibonacci(startWaiting time.Duration, action func() error)
Fibonacci performs retry function with the waiting duration calculated using Fibonacci sequence.

It will wait for firstWaiting to do the first retry

func (*Instance) Linear

func (i *Instance) Linear(backoff, incrementStep time.Duration, action func() error)
Linear performs retry function with linearly incremental backoff time.

It will wait for firstWaiting to do the first retry, and then increase the waiting time by incrementStep for each next retry

func (*Instance) NoBackoff

func (i *Instance) NoBackoff(action func() error)

NoBackoff is a shortcut to call Do(0, action). It will retry immediately and don't wait at all.

func (*Instance) Polynomial

func (i *Instance) Polynomial(baseTime time.Duration, degree int64, action func() error)
Polynomial performs retry function with backoff time calculated by Polynomial function.

It will wait for baseTime to do the first retry, and then increase the waiting time by time = attempt ^ degree * baseTime

func (*Instance) Quadratic

func (i *Instance) Quadratic(baseTime time.Duration, action func() error)
Quadratic performs retry function with backoff time calculated by quadratic function.

It will wait for baseTime to do the first retry, and then increase the waiting time by time = attempt ^ 2 * baseTime

Jump to

Keyboard shortcuts

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