backoff

package module
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Jan 16, 2021 License: MIT Imports: 5 Imported by: 0

README

backoff

GoDev Build Status Coverage Status

Exponential backoff algorithm with randomized jitter

Example

package main

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

        "github.com/go-tk/backoff"
)

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        _ = cancel
        b := backoff.New(backoff.Options{
                MinDelay:            100 * time.Millisecond,        // default
                MaxDelay:            100 * time.Second,             // default
                DelayFactor:         2,                             // default
                MaxDelayJitter:      1,                             // default
                DelayFunc:           backoff.DelayWithContext(ctx), // with respect to ctx
                MaxNumberOfAttempts: 100,                           // default
        })
        req, err := http.NewRequestWithContext(ctx, "GET", "http://example.com/", nil)
        if err != nil {
                log.Fatal(err)
        }
        for {
                resp, err := http.DefaultClient.Do(req)
                if err != nil {
                        if err2 := b.Do(); err2 != nil { // delay
                                log.Printf("failed to back off; err=%q", err2)
                                log.Fatal(err)
                        }
                        continue // retry
                }
                resp.Body.Close()
                if resp.StatusCode/100 == 5 {
                        err := fmt.Errorf("http server error; httpStatusCode=%v", resp.StatusCode)
                        if err2 := b.Do(); err2 != nil { // delay
                                log.Printf("failed to back off; err=%q", err2)
                                log.Fatal(err)
                        }
                        continue // retry
                }
                fmt.Println(resp.StatusCode)
                return
        }
        // Output:
        // 200
}

Documentation

Overview

Package backoff implements the exponential backoff algorithm with randomized jitter.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrTooManyAttempts = errors.New("backoff: too many attempts")

ErrTooManyAttempts is returned when the maximum number of attempts to back off has been reached.

Functions

This section is empty.

Types

type Backoff

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

Backoff represents an instance of the exponential backoff algorithm.

Example
package main

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

	"github.com/go-tk/backoff"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	_ = cancel
	b := backoff.New(backoff.Options{
		MinDelay:            100 * time.Millisecond,        // default
		MaxDelay:            100 * time.Second,             // default
		DelayFactor:         2,                             // default
		MaxDelayJitter:      1,                             // default
		DelayFunc:           backoff.DelayWithContext(ctx), // with respect to ctx
		MaxNumberOfAttempts: 100,                           // default
	})
	req, err := http.NewRequestWithContext(ctx, "GET", "http://example.com/", nil)
	if err != nil {
		log.Fatal(err)
	}
	for {
		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			if err2 := b.Do(); err2 != nil { // delay
				log.Printf("failed to back off; err=%q", err2)
				log.Fatal(err)
			}
			continue // retry
		}
		resp.Body.Close()
		if resp.StatusCode/100 == 5 {
			err := fmt.Errorf("http server error; httpStatusCode=%v", resp.StatusCode)
			if err2 := b.Do(); err2 != nil { // delay
				log.Printf("failed to back off; err=%q", err2)
				log.Fatal(err)
			}
			continue // retry
		}
		fmt.Println(resp.StatusCode)
		return
	}
}
Output:
200

func New

func New(options Options) *Backoff

New creates an instance of the exponential backoff algorithm with the given options.

func (*Backoff) Do

func (b *Backoff) Do() error

Do delays for a time period determined based on the options.

type DelayFunc

type DelayFunc func(event <-chan struct{}) (err error)

DelayFunc is the type of the function delaying until the given event happens.

func DelayWithContext

func DelayWithContext(ctx context.Context) DelayFunc

DelayWithContext makes a DelayFunc with respect to the given ctx.

type Options

type Options struct {
	// Value < 1 is equivalent to 100ms.
	MinDelay time.Duration

	// Value < 1 is equivalent to 100s.
	MaxDelay time.Duration

	// Value < 1 is equivalent to 2.
	DelayFactor float64

	// Value < 0 is equivalent to 0.
	// Value == 0 is equivalent to 1.
	MaxDelayJitter float64

	// Value nil is equivalent to:
	//  func(event <-chan struct{}) error {
	//      <-event
	//      return nil
	//  }
	DelayFunc DelayFunc

	// Value < 0 is equivalent to 0.
	// value == 0 is equivalent to 100.
	MaxNumberOfAttempts int
}

Options represents options for backoffs.

The pseudo code for the delay calculation:

if delay is not initialized
    delay = MIN_DELAY
else
    delay = min(delay * DELAY_FACTOR, MAX_DELAY)

delay_jitter = random(-MAX_DELAY_JITTER, MAX_DELAY_JITTER)
delay_with_jitter = delay * (1 + delay_jitter)

Jump to

Keyboard shortcuts

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