asyncretry

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2022 License: MIT Imports: 5 Imported by: 0

README

Async-retry

Go Reference

Async-retry controls asynchronous retries in Go, and can be shutdown gracefully.

Main features of Async-retry are

  • Disable cancellation of context passed to function as an argument
  • Keep value of context passed to function as an argument
  • Set timeout for each function call
  • Recover from panic
  • Control retry with delegating to https://github.com/avast/retry-go
  • Gracefully shutdown

You can find other features or settings in options.go

Example

package asyncretry_test

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

	asyncretry "github.com/Kyash/async-retry"
)

func ExampleAsyncRetry() {
	mux := http.NewServeMux()
	asyncRetry := asyncretry.NewAsyncRetry()
	mux.HandleFunc(
		"/hello",
		func(w http.ResponseWriter, r *http.Request) {
			var ctx = r.Context()
			if err := asyncRetry.Do(
				ctx,
				func(ctx context.Context) error {
					// do task
					// ...
					return nil
				},
				func(err error) {
					if err != nil {
						log.Println(err.Error())
					}
				},
				asyncretry.Attempts(5),
				asyncretry.Timeout(8*time.Second),
			); err != nil {
				// asyncRetry is in shutdown
				log.Println(err.Error())
			}
			fmt.Fprintf(w, "Hello")
		},
	)
	srv := &http.Server{Handler: mux}

	ch := make(chan struct{})
	go func() {
		sigint := make(chan os.Signal, 1)
		signal.Notify(sigint, os.Interrupt)
		<-sigint
		if err := srv.Shutdown(context.Background()); err != nil {
			log.Printf("HTTP server Shutdown: %v", err)
		}
		if err := asyncRetry.Shutdown(context.Background()); err != nil {
			log.Printf("AsyncRetry Shutdown: %v", err)
		}
		close(ch)
	}()

	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
		log.Fatalf("HTTP server ListenAndServe: %v", err)
	}

	<-ch
}

UseCase

We wrote a blog about this libarary.

Contributing

We are always welcome your contribution!

If you find bugs or want to add new features, please raise issues.

License

MIT License

Copyright (c) 2022 Kyash

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultConfig = Config{
	// contains filtered or unexported fields
}
View Source
var ErrInShutdown = fmt.Errorf("AsyncRetry is in shutdown")

Functions

func IsRecoverable

func IsRecoverable(err error) bool

IsRecoverable checks if error is recoverable

func Unrecoverable

func Unrecoverable(err error) error

Unrecoverable wraps error.

func WithoutCancel

func WithoutCancel(ctx context.Context) context.Context

WithoutCancel returns a context that is never canceled.

Types

type AsyncRetry

type AsyncRetry interface {
	// Do calls f in a new goroutine, and retry if necessary. When finished, `finish` is called regardless of success or failure exactly once.
	// Non-nil error is always `ErrInShutdown` that will be returned when AsyncRetry is in shutdown.
	Do(ctx context.Context, f RetryableFunc, finish FinishFunc, opts ...Option) error

	// Shutdown gracefully shuts down AsyncRetry without interrupting any active `Do`.
	// Shutdown works by first stopping to accept new `Do` request, and then waiting for all active `Do`'s background goroutines to be finished.
	// Multiple call of Shutdown is OK.
	Shutdown(ctx context.Context) error
}
Example
package main

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

	asyncretry "github.com/Kyash/async-retry"
)

func main() {
	mux := http.NewServeMux()
	asyncRetry := asyncretry.NewAsyncRetry()
	mux.HandleFunc(
		"/hello",
		func(w http.ResponseWriter, r *http.Request) {
			var ctx = r.Context()
			if err := asyncRetry.Do(
				ctx,
				func(ctx context.Context) error {
					// do task
					// ...
					return nil
				},
				func(err error) {
					if err != nil {
						log.Println(err.Error())
					}
				},
				asyncretry.Attempts(5),
				asyncretry.Timeout(8*time.Second),
			); err != nil {
				// asyncRetry is in shutdown
				log.Println(err.Error())
			}
			fmt.Fprintf(w, "Hello")
		},
	)
	srv := &http.Server{Handler: mux}

	ch := make(chan struct{})
	go func() {
		sigint := make(chan os.Signal, 1)
		signal.Notify(sigint, os.Interrupt)
		<-sigint
		if err := srv.Shutdown(context.Background()); err != nil {
			log.Printf("HTTP server Shutdown: %v", err)
		}
		if err := asyncRetry.Shutdown(context.Background()); err != nil {
			log.Printf("AsyncRetry Shutdown: %v", err)
		}
		close(ch)
	}()

	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
		log.Fatalf("HTTP server ListenAndServe: %v", err)
	}

	<-ch
}
Output:

func NewAsyncRetry

func NewAsyncRetry() AsyncRetry

type Config

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

type FinishFunc

type FinishFunc func(error)

type OnRetryFunc

type OnRetryFunc func(n uint, err error)

OnRetryFunc is a signature of OnRetry function n = 0-indexed count of attempts.

type Option

type Option func(*Config)

Option represents an option for async-retry.

func Attempts

func Attempts(attempts uint) Option

Attempts set count of retry If set 0 or 1, only initial call is permitted If set 2, initial call and one retry are permitted Note: retry-go supports 0 which means infinity, but we don't support that

func CancelWhenConfigContextCanceled

func CancelWhenConfigContextCanceled(cancel bool) Option

CancelWhenConfigContextCanceled sets boolean If true, cancel the context specified as an argument of RetryableFunc when c.context is canceled

func CancelWhenShutdown

func CancelWhenShutdown(cancel bool) Option

CancelWhenShutdown sets boolean If true, cancel the context specified as an argument of RetryableFunc when Shutdown is called

func Context

func Context(ctx context.Context) Option

Context sets context If context is canceled, stop next retry

func Delay

func Delay(delay time.Duration) Option

Delay sets delay between retry Interval between retry equals to the sum of c.delay << n and random number in the half-open interval [0,c.maxJitter)

func MaxJitter

func MaxJitter(maxJitter time.Duration) Option

MaxJitter sets the maximum random jitter See comment of Delay

func OnRetry

func OnRetry(onRetry OnRetryFunc) Option

OnRetry sets OnRetryFunc

func RetryIf

func RetryIf(retryIf RetryIfFunc) Option

RetryIf sets RetryIfFunc If retryIf returns false, retry will be stopped

func Timeout

func Timeout(timeout time.Duration) Option

Timeout sets timeout for RetryableFunc 0 or value less than 0 means no timeout. In most cases, setting timeout is preferable.

type RetryIfFunc

type RetryIfFunc func(error) bool

RetryIfFunc is s signature of retry if function

type RetryableFunc

type RetryableFunc func(ctx context.Context) error

Jump to

Keyboard shortcuts

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