Skip to content

Latest commit

 

History

History
259 lines (190 loc) · 6.4 KB

README.md

File metadata and controls

259 lines (190 loc) · 6.4 KB

Go Retry

Go Reference build_pr Go Report Card Built with WeBuild License: MIT

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(...)
}

Links