Skip to content

Import path: gitlab.soludian.com/soludian/fountain/libs/resilient/backoff

backoff

go
import "gitlab.soludian.com/soludian/fountain/libs/resilient/backoff"

Package backoff implements backoff algorithms for retrying operations.

Use Retry function for retrying operations that may fail. If Retry does not meet your needs, copy/paste the function into your project and modify as you wish.

There is also Ticker type similar to time.Ticker. You can use it if you need to work with channels.

See Examples section below for usage examples.

Index

Constants

Các giá trị mặc định cho ExponentialBackOff.

go
const (
    DefaultInitialInterval     = 500 * time.Millisecond
    DefaultRandomizationFactor = 0.5
    DefaultMultiplier          = 1.5
    DefaultMaxInterval         = 60 * time.Second
    DefaultMaxElapsedTime      = 15 * time.Minute
)

Stop chỉ ra rằng không nên retry thêm nữa cho sử dụng trong NextBackOff().

go
const Stop time.Duration = -1

Variables

go
var ErrBreaker = Permanent(errors.New("breaker stopped retry"))

SystemClock triển khai interface Clock sử dụng time.Now().

go
var SystemClock = systemClock{}

func Permanent

go
func Permanent(err error) error

Permanent bao bọc lỗi được cung cấp trong *PermanentError.

func Retry

go
func Retry(o Operation, b BackOff) error

Retry hàm o cho đến khi nó không trả về lỗi hoặc BackOff dừng. o được đảm bảo sẽ chạy ít nhất một lần.

Nếu o trả về *PermanentError, hàm sẽ không được thử lại, và lỗi được bao bọc sẽ được trả về.

Retry sẽ làm cho goroutine ngủ trong khoảng thời gian trả về bởi BackOff sau khi hàm thất bại trả về.

Example

go
// An operation that may fail.
operation := func() error {
	return nil // or an error
}

err := Retry(operation, NewExponentialBackOff())
if err != nil {
	// Handle error.
	return
}

// Operation is successful.

Example (With Context)

go
// nolint: govet
// A context
ctx := context.Background()

// An operation that may fail.
operation := func() error {
	return nil // or an error
}

b := WithContext(NewExponentialBackOff(), ctx)

err := Retry(operation, b)
if err != nil {
	// Handle error.
	return
}

// Operation is successful.

func RetryBreaker

go
func RetryBreaker(o Operation, b BackOff, breaker Breaker) error

RetryBreaker tương tự như Retry nhưng nhận thêm đối số breaker và sẽ dừng retry ngay lập tức nếu breaker trả về true.

func RetryBreakerWithData

go
func RetryBreakerWithData[T any](o OperationWithData[T], b BackOff, breaker Breaker) (T, error)

RetryBreakerWithData tương tự như RetryWithData nhưng có thêm đối số breaker để dừng retry ngay lập tức nếu breaker trả về true.

func RetryNotify

go
func RetryNotify(operation Operation, b BackOff, notify Notify) error

RetryNotify gọi hàm thông báo với lỗi và thời gian chờ cho mỗi lần thử thất bại trước khi ngủ.

func RetryNotifyWithBreaker

go
func RetryNotifyWithBreaker(operation Operation, b BackOff, notify Notify, breaker Breaker) error

RetryNotifyWithBreaker giống như RetryNotify nhưng có thêm breaker để dừng retry ngay lập tức.

func RetryNotifyWithData

go
func RetryNotifyWithData[T any](operation OperationWithData[T], b BackOff, notify Notify) (T, error)

RetryNotifyWithData giống như RetryNotify nhưng trả về dữ liệu trong phản hồi.

func RetryNotifyWithDataAndBreaker

go
func RetryNotifyWithDataAndBreaker[T any](operation OperationWithData[T], b BackOff, notify Notify, breaker Breaker) (T, error)

RetryNotifyWithDataAndBreaker giống như RetryNotifyWithData nhưng có thêm breaker.

func RetryNotifyWithTimer

go
func RetryNotifyWithTimer(operation Operation, b BackOff, notify Notify, t Timer) error

RetryNotifyWithTimer gọi hàm thông báo với lỗi và thời gian chờ sử dụng Timer được cung cấp cho mỗi lần thử thất bại trước khi ngủ. Một timer mặc định sử dụng hệ thống timer sẽ được sử dụng khi nil được truyền vào.

func RetryNotifyWithTimerAndBreaker

go
func RetryNotifyWithTimerAndBreaker(operation Operation, b BackOff, notify Notify, t Timer, breaker Breaker) error

RetryNotifyWithTimerAndBreaker giống như RetryNotifyWithTimer nhưng có thêm breaker để dừng retry ngay lập tức.

func RetryNotifyWithTimerAndData

go
func RetryNotifyWithTimerAndData[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer) (T, error)

RetryNotifyWithTimerAndData giống như RetryNotifyWithTimer nhưng trả về dữ liệu trong phản hồi.

func RetryNotifyWithTimerAndDataAndBreaker

go
func RetryNotifyWithTimerAndDataAndBreaker[T any](operation OperationWithData[T], b BackOff, notify Notify, t Timer, breaker Breaker) (T, error)

RetryNotifyWithTimerAndDataAndBreaker giống như RetryNotifyWithTimerAndData nhưng có thêm breaker.

func RetryWithData

go
func RetryWithData[T any](o OperationWithData[T], b BackOff) (T, error)

RetryWithData giống như Retry nhưng trả về dữ liệu trong phản hồi.

type BackOff

BackOff là một chính sách backoff cho retrying an operation.

go
type BackOff interface {
    // NextBackOff trả về khoảng thời gian chờ trước khi retrying the operation,
    // hoặc backoff. Stop để chỉ ra rằng không nên retry thêm nữa.
    //
    // Vd sử dụng:
    //
    // 	duration := backoff.NextBackOff();
    // 	if (duration == backoff.Stop) {
    // 		// Không retry operation.
    // 	} else {
    // 		// Ngủ trong khoảng thời gian và retry operation.
    // 	}
    //
    NextBackOff() time.Duration

    // Copy trả về một bản sao của BackOff với reset đã được gọi
    Copy() BackOff

    // Reset về trạng thái ban đầu.
    Reset()
}

func WithMaxRetries

go
func WithMaxRetries(b BackOff, max uint64) BackOff

WithMaxRetries creates a wrapper around another BackOff, which will return Stop if NextBackOff() has been called too many times since the last time Reset() was called

Note: Implementation is not thread-safe.

type BackOffContext

BackOffContext is a backoff policy that stops retrying after the context is canceled.

go
type BackOffContext interface {
    BackOff
    Context() context.Context
}

func WithContext

go
func WithContext(b BackOff, ctx context.Context) BackOffContext

WithContext returns a BackOffContext with context ctx

ctx must not be nil

type Breaker

Breaker là một hàm kiểm tra điều kiện tiếp tục hoặc dừng việc retry. Hàm trả về giá trị `true` nếu cần dừng retry ngay lập tức, và `false` nếu tiếp tục retry. Breaker có thể được sử dụng để triển khai các cơ chế dừng lại dựa trên các điều kiện cụ thể như vượt quá số lần retry, đạt đến một ngưỡng timeout, hoặc các điều kiện do người dùng định nghĩa.

go
type Breaker func() bool

type Clock

Clock là một interface trả về thời gian hiện tại cho BackOff.

go
type Clock interface {
    Now() time.Time
}

type ConstantBackOff

ConstantBackOff là một chính sách backoff luôn trả về cùng một khoảng thời gian backoff. Điều này trái ngược với chính sách backoff exponential, trả về một khoảng thời gian dài hơn khi gọi NextBackOff() nhiều lần.

go
type ConstantBackOff struct {
    Interval time.Duration
}

func NewConstantBackOff

go
func NewConstantBackOff(d time.Duration) *ConstantBackOff

func (*ConstantBackOff) Copy

go
func (b *ConstantBackOff) Copy() BackOff

func (*ConstantBackOff) NextBackOff

go
func (b *ConstantBackOff) NextBackOff() time.Duration

func (*ConstantBackOff) Reset

go
func (b *ConstantBackOff) Reset()

type ExponentialBackOff

ExponentialBackOff là một triển khai backoff tăng dần thời gian chờ cho mỗi lần thử lại bằng cách sử dụng hàm ngẫu nhiên tăng theo cấp số nhân.

NextBackOff() được tính toán bằng công thức sau:

randomized interval = RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])

Nói cách khác, NextBackOff() sẽ nằm trong khoảng phần trăm của randomization factor dưới và trên retry interval.

Vd, với các tham số sau:

RetryInterval = 2
RandomizationFactor = 0.5
Multiplier = 2

thời gian chờ thực tế được sử dụng trong lần thử lại tiếp theo sẽ nằm trong khoảng từ 1 đến 3 giây, nhân với cấp số nhân, tức là từ 2 đến 6 giây.

Lưu ý: MaxInterval giới hạn RetryInterval chứ không phải randomized interval.

Nếu thời gian trôi qua kể từ khi một instance của ExponentialBackOff được tạo vượt quá MaxElapsedTime, thì phương thức NextBackOff() sẽ bắt đầu trả về backoff.Stop.

Thời gian trôi qua có thể được reset bằng cách gọi Reset().

Vd: Với các tham số mặc định sau, cho 10 lần thử, và giả sử chúng ta vượt quá MaxElapsedTime ở lần thử thứ 10:

Request #  RetryInterval (seconds)  Randomized Interval (seconds)

 1          0.5                     [0.25,   0.75]
 2          0.75                    [0.375,  1.125]
 3          1.125                   [0.562,  1.687]
 4          1.687                   [0.8435, 2.53]
 5          2.53                    [1.265,  3.795]
 6          3.795                   [1.897,  5.692]
 7          5.692                   [2.846,  8.538]
 8          8.538                   [4.269, 12.807]
 9         12.807                   [6.403, 19.210]
10         19.210                   backoff.Stop

Lưu ý: Triển khai không an toàn cho thread.

go
type ExponentialBackOff struct {
    InitialInterval     time.Duration
    RandomizationFactor float64
    Multiplier          float64
    MaxInterval         time.Duration
    // Sau MaxElapsedTime, ExponentialBackOff trả về Stop.
    // Nó không bao giờ dừng nếu MaxElapsedTime == 0.
    MaxElapsedTime time.Duration
    Stop           time.Duration
    Clock          Clock
    // contains filtered or unexported fields
}

func NewExponentialBackOff

go
func NewExponentialBackOff(opts ...ExponentialBackOffOpts) *ExponentialBackOff

NewExponentialBackOff tạo một instance của ExponentialBackOff sử dụng các giá trị mặc định.

func (*ExponentialBackOff) Copy

go
func (b *ExponentialBackOff) Copy() BackOff

Copy trả về một bản sao của BackOff với reset đã được gọi

func (*ExponentialBackOff) GetElapsedTime

go
func (b *ExponentialBackOff) GetElapsedTime() time.Duration

GetElapsedTime trả về thời gian đã trôi qua kể từ khi một instance của ExponentialBackOff được tạo và được reset khi Reset() được gọi.

Thời gian đã trôi qua được tính toán bằng cách sử dụng time.Now().UnixNano(). Nó an toàn để gọi ngay cả khi chính sách backoff đang được sử dụng bởi một ticker đang chạy.

func (*ExponentialBackOff) NextBackOff

go
func (b *ExponentialBackOff) NextBackOff() time.Duration

NextBackOff tính toán khoảng thời gian backoff tiếp theo bằng công thức:

Randomized interval = RetryInterval * (1 ± RandomizationFactor)

func (*ExponentialBackOff) Reset

go
func (b *ExponentialBackOff) Reset()

Reset khoảng thời gian trở lại khoảng thời gian thử lại ban đầu và khởi động lại bộ đếm thời gian. Reset phải được gọi trước khi sử dụng b.

type ExponentialBackOffOpts

ExponentialBackOffOpts là một kiểu hàm được sử dụng để cấu hình các tùy chọn của ExponentialBackOff.

go
type ExponentialBackOffOpts func(*ExponentialBackOff)

func WithClockProvider

go
func WithClockProvider(clock Clock) ExponentialBackOffOpts

WithClockProvider đặt clock được sử dụng để đo thời gian.

func WithInitialInterval

go
func WithInitialInterval(duration time.Duration) ExponentialBackOffOpts

WithInitialInterval đặt khoảng thời gian ban đầu giữa các lần thử lại.

func WithMaxElapsedTime

go
func WithMaxElapsedTime(duration time.Duration) ExponentialBackOffOpts

WithMaxElapsedTime đặt tổng thời gian tối đa cho các lần thử lại.

func WithMaxInterval

go
func WithMaxInterval(duration time.Duration) ExponentialBackOffOpts

WithMaxInterval đặt khoảng thời gian tối đa giữa các lần thử lại.

func WithMultiplier

go
func WithMultiplier(multiplier float64) ExponentialBackOffOpts

WithMultiplier đặt multiplier để tăng khoảng thời gian sau mỗi lần thử lại.

func WithRandomizationFactor

go
func WithRandomizationFactor(randomizationFactor float64) ExponentialBackOffOpts

WithRandomizationFactor đặt randomization factor để thêm jitter vào các khoảng thời gian.

func WithRetryStopDuration

go
func WithRetryStopDuration(duration time.Duration) ExponentialBackOffOpts

WithRetryStopDuration đặt khoảng thời gian sau đó các lần thử lại nên dừng.

type FibonacciBackOff

FibonacciBackOff là một chính sách backoff dựa trên dãy số Fibonacci, nhân khoảng thời gian chờ ban đầu với giá trị Fibonacci tương ứng cho mỗi lần retry.

go
type FibonacciBackOff struct {
    Factor  time.Duration
    Attempt uint
}

func NewFibonacciBackOff

go
func NewFibonacciBackOff(factor time.Duration) *FibonacciBackOff

NewFibonacciBackOff tạo một đối tượng FibonacciBackOff với hệ số Fibonacci.

func (*FibonacciBackOff) Copy

go
func (b *FibonacciBackOff) Copy() BackOff

func (*FibonacciBackOff) NextBackOff

go
func (b *FibonacciBackOff) NextBackOff() time.Duration

func (*FibonacciBackOff) Reset

go
func (b *FibonacciBackOff) Reset()

type IncrementalBackOff

IncrementalBackOff là một chính sách backoff tăng dần, tăng khoảng thời gian chờ ban đầu lên một lượng cụ thể cho mỗi lần retry.

go
type IncrementalBackOff struct {
    Initial   time.Duration
    Increment time.Duration
    Attempt   uint
}

func NewIncrementalBackOff

go
func NewIncrementalBackOff(initial, increment time.Duration) *IncrementalBackOff

NewIncrementalBackOff tạo một đối tượng IncrementalBackOff với khoảng thời gian ban đầu và gia số tăng thêm cho mỗi lần retry.

func (*IncrementalBackOff) Copy

go
func (b *IncrementalBackOff) Copy() BackOff

func (*IncrementalBackOff) NextBackOff

go
func (b *IncrementalBackOff) NextBackOff() time.Duration

func (*IncrementalBackOff) Reset

go
func (b *IncrementalBackOff) Reset()

type LinearBackOff

LinearBackOff là một chính sách backoff theo tuyến tính, nhân khoảng thời gian chờ ban đầu với số lần retry.

go
type LinearBackOff struct {
    Factor  time.Duration
    Attempt uint
}

func NewLinearBackOff

go
func NewLinearBackOff(factor time.Duration) *LinearBackOff

NewLinearBackOff tạo một đối tượng LinearBackOff với hệ số tuyến tính.

func (*LinearBackOff) Copy

go
func (b *LinearBackOff) Copy() BackOff

func (*LinearBackOff) NextBackOff

go
func (b *LinearBackOff) NextBackOff() time.Duration

func (*LinearBackOff) Reset

go
func (b *LinearBackOff) Reset()

type Notify

Notify là một hàm thông báo khi có lỗi. Nó nhận lỗi của hàm và thời gian chờ nếu hàm thất bại (trả về lỗi).

LƯU Ý rằng nếu chính sách backoff yêu cầu dừng thử lại, hàm thông báo sẽ không được gọi.

go
type Notify func(error, time.Duration)

type Operation

Operation là một hàm được thực thi bởi Retry() hoặc RetryNotify(). Hàm này sẽ được thử lại theo chính sách backoff nếu trả về lỗi.

go
type Operation func() error

type OperationWithData

OperationWithData là một hàm được thực thi bởi RetryWithData() hoặc RetryNotifyWithData(). Hàm này sẽ được thử lại theo chính sách backoff nếu trả về lỗi.

go
type OperationWithData[T any] func() (T, error)

type PermanentError

PermanentError báo hiệu rằng hàm không nên được thử lại.

go
type PermanentError struct {
    Err error
}

func (*PermanentError) Error

go
func (e *PermanentError) Error() string

func (*PermanentError) Is

go
func (e *PermanentError) Is(target error) bool

func (*PermanentError) Unwrap

go
func (e *PermanentError) Unwrap() error

type StopBackOff

StopBackOff là một chính sách backoff cố định luôn trả về backoff.Stop cho NextBackOff(), nghĩa là operation không bao giờ được retry.

go
type StopBackOff struct{}

func (*StopBackOff) Copy

go
func (b *StopBackOff) Copy() BackOff

func (*StopBackOff) NextBackOff

go
func (b *StopBackOff) NextBackOff() time.Duration

func (*StopBackOff) Reset

go
func (b *StopBackOff) Reset()

type Ticker

Ticker chứa một kênh cung cấp `ticks` của đồng hồ tại các thời điểm được báo cáo bởi BackOff.

Ticks sẽ tiếp tục đến khi hoạt động trước đó vẫn đang chạy, vì vậy các hoạt động mất thời gian để thất bại có thể chạy liên tiếp nhanh chóng.

go
type Ticker struct {
    C <-chan time.Time
    // contains filtered or unexported fields
}
Example

go
// An operation that may fail.
operation := func() error {
	return nil // or an error
}

ticker := NewTicker(NewExponentialBackOff())

var err error

// Ticks will continue to arrive when the previous operation is still running,
// so operations that take a while to fail could run in quick succession.
for range ticker.C {
	if err = operation(); err != nil {
		log.Println(err, "will retry...")
		continue
	}

	ticker.Stop()
	break
}

if err != nil {
	// Operation has failed.
	return
}

// Operation is successful.

func NewTicker

go
func NewTicker(b BackOff) *Ticker

NewTicker trả về một Ticker mới chứa một kênh sẽ gửi thời gian tại các thời điểm được chỉ định bởi BackOff. Ticker được đảm bảo sẽ tick ít nhất một lần. Kênh sẽ đóng khi phương thức Stop được gọi hoặc BackOff dừng. Không an toàn khi thao tác với chính sách backoff đã cung cấp (đặc biệt là gọi NextBackOff hoặc Reset) trong khi ticker đang chạy.

func NewTickerWithTimer

go
func NewTickerWithTimer(b BackOff, timer Timer) *Ticker

NewTickerWithTimer trả về một Ticker mới với một timer tùy chỉnh. Một timer mặc định sử dụng hệ thống timer sẽ được sử dụng khi nil được truyền vào.

func (*Ticker) Stop

go
func (t *Ticker) Stop()

Stop tắt ticker. Sau khi Stop, không còn ticks nào sẽ được gửi.

type Timer

go
type Timer interface {
    Start(duration time.Duration)
    Stop()
    C() <-chan time.Time
}

type ZeroBackOff

ZeroBackOff là một chính sách backoff cố định với thời gian backoff luôn bằng zero, nghĩa là operation được retry ngay lập tức mà không chờ đợi, vô thời hạn.

go
type ZeroBackOff struct{}

func (*ZeroBackOff) Copy

go
func (b *ZeroBackOff) Copy() BackOff

func (*ZeroBackOff) NextBackOff

go
func (b *ZeroBackOff) NextBackOff() time.Duration

func (*ZeroBackOff) Reset

go
func (b *ZeroBackOff) Reset()

Generated by gomarkdoc