retry

package module
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Apr 7, 2019 License: MIT Imports: 5 Imported by: 0

README

retry

retry is a package that enables retrying code.

GoDoc Build Status codecov Go Report Card

It has:

  • a simple api, only one public function!
  • sane defaults
  • validation logic to catch errors and optimize allocations
  • a thread safe model
  • support for context.Context
  • a fun ergonomic syntax(at least I think soo 😆)

Installation

go get github.com/codyoss/retry

Examples

An example calling a function that does not return an error:

var result int
retry.It(context.Background(), retry.ExponentialBackoff, func(ctx context.Context) (err error) {
    result = squareOnThirdAttempt()
    if result == 0 {
        return retry.Me
    }
    return
})
fmt.Println(result)
//Output: 9

An alternate syntax that does the same thing as above:

var result int
// You could also create your own backoff policy
backoff := retry.ExponentialBackoff
// This just calls the package level It function under the hood.
backoff.It(context.Background(), func(ctx context.Context) (err error) {
    result = squareOnThirdAttempt()
    if result == 0 {
        return retry.Me
    }
    return
})
fmt.Println(result)
//Output: 9

An example calling a function that returns an error:

var result int
retry.It(context.Background(), retry.ExponentialBackoff, func(ctx context.Context) (err error) {
    result, err = squareOnThirdAttempt()
    return
})
fmt.Println(result)
// Output: 9

An example of what happens when retries are exceeded:

// Create your own retry policy. It can be used across goroutines safely.
b := &retry.ExponentialBackoff{
    Attempts:     5,
    InitialDelay: 0 * time.Millisecond,
}
attempt := 0

// final error will be returned if retries are exceeded
err := retry.It(context.Background(), b, func(ctx context.Context) error {
    attempt++
    return fmt.Errorf("I failed %d times 😢", attempt)
})
fmt.Println(err)
// Output: I failed 5 times 😢

retry also supports calling code that is context aware!

noopFn := func(ctx context.Context) {}

// can you use the context to set a max amount time to retry for
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()

// the context passed in is forwarded to the function provided
err := retry.It(ctx, retry.ConstantDelay, func(ctx context.Context) (err error) {
    noopFn(ctx)
    return retry.Me
})

fmt.Printf("%v\n", err)
// Output: context deadline exceeded

For full examples with more documentation see the examples folder

Disclaimer

Until this api hits v0.1.0 it might change a bit. After that I will try to keep things rather stable. After I have gotten enough feedback I will v1.0.0 and make the same promise Go does. Cheers!

Documentation

Overview

Package retry provides an simple api to retry function calls in a thread safe way.

Index

Constants

View Source
const (
	// Forever is a shorthand for a time.Duration of one year. This value can be used as an input to ExponentialBackoff
	// for the MaxDelay field should the user not want to ever hit that limit.
	Forever = 365 * 24 * 60 * time.Minute
)

Variables

View Source
var (
	// ConstantDelay is a backoff policy that will attempt a call 5 times with 500 milliseconds between
	// subsequent calls.
	ConstantDelay = &Backoff{
		Attempts:     5,
		InitialDelay: 500 * time.Millisecond,
		Factor:       1,
	}
	// ExponentialBackoff provides a, sane, default exponential backoff policy.
	ExponentialBackoff = &Backoff{
		Attempts:     5,
		InitialDelay: 500 * time.Millisecond,
		MaxDelay:     8 * time.Second,
		Factor:       2.0,
		Jitter:       0.1,
	}

	// Me is an error that can be returned in from a function. To be used in the function passed to It if no other
	// error makes sense or if you don't care to return that actual error. This is error variable is simply sugar.
	Me = errors.New("retry me")
)

Functions

func It

func It(ctx context.Context, b *Backoff, fn func(context.Context) error) (err error)

It takes a context, an ExponentialBackoff, and a func that returns an err. If the function passed to this method returns an error it will be retired. If the number of attempts, declared in ExponentialBackoff, is exceeded the final error the func returns will be returned to the caller.

The context passed into this method can act as an max timeout over all invocations. This is total time, it is not reset should your code need to retry. The context will also passed into the function provided. Thus, any code you call within the retry block can share the same parent context.

This function makes use of closures so any variables you would like to capture should be declared outside the invocation of this method.

Types

type Backoff added in v0.0.4

type Backoff struct {
	// Attempts it the max number of times a function will be retried. Will always be treaded as a value >= 1.
	Attempts int
	// InitialDelay is the starting delay should the first attempt fail.
	InitialDelay time.Duration
	// MaxDelay is the max amount of time to try in between retry attempts.
	MaxDelay time.Duration
	// Factor is the amount that will be multiplied to the previous delay to calculate the next delay. This value
	// will always be treaded as a value >= 1.0. A value of 2.0 would be a standard exponential backoff.
	Factor float64
	// Jitter is a way to add a bit of randomness into your delay. Setting this value helps avoid what is known as the
	// thundering herd problem. For example if a value of .1 is set and your delay is 500 milliseconds the Jitter would
	// transform that value into a number between 490 and 510 milliseconds.
	Jitter float64
	// contains filtered or unexported fields
}

Backoff holds the configuration of a backoff policy. Once values are set and this backoff is used any modification to this struct will not affect behavior. Fields get frozen to un-exported variables upon first use.

func (*Backoff) It added in v0.0.5

func (b *Backoff) It(ctx context.Context, fn func(context.Context) error) (err error)

It is a convenience method to call the package level function It.

Directories

Path Synopsis
examples
basic command
context command
err-func command
err-returned command

Jump to

Keyboard shortcuts

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