package flaky

Import Path
	go.pact.im/x/flaky (on go.dev)

Dependency Relation
	imports 7 packages, and imported by 0 packages

Involved Source Files backoff.go deadline.go debounce.go Package flaky implements mechanisms for executing flaky operations. jitter.go once.go permanent.go retry.go schedule.go watchdog.go
Code Examples package main import ( "context" "fmt" "go.pact.im/x/flaky" "net/http" "net/http/httputil" "time" ) func main() { ctx := context.Background() executor := flaky.Retry(flaky.Limit(5, flaky.Exp2(time.Second))) req, _ := http.NewRequest(http.MethodGet, "https://example.com", nil) client := http.DefaultClient var dump []byte var err error err = executor.Execute(ctx, func(ctx context.Context) error { ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() var resp *http.Response resp, err = client.Do(req.WithContext(ctx)) if err != nil { return err } dump, err = httputil.DumpResponse(resp, false) return err }) if err != nil { panic(err) } fmt.Println(string(dump)) }
Package-Level Type Names (total 20, in which 13 are exported)
/* sort exporteds by: | */
Backoff is a function that, given the current count of retries, returns backoff delay before the next attempt, or false if an executor should stop with the last error. Backoff implements the BackoffProvider interface. Backoff : BackoffProvider func Constant(xs ...time.Duration) Backoff func Exp2(unit time.Duration) Backoff func Limit(limit uint, backoff Backoff) Backoff func Backoff.Backoff() Backoff func BackoffProvider.Backoff() Backoff func Jitter.Backoff(b Backoff, v JitterInterval) Backoff func Limit(limit uint, backoff Backoff) Backoff func Jitter.Backoff(b Backoff, v JitterInterval) Backoff
BackoffProvider provides a potentially stateful backoff function for executing an operation. ( BackoffProvider) Backoff() Backoff Backoff func Retry(b BackoffProvider) *RetryExecutor
DebounceExecutor is an executor that debounces an operation. That is, it performs an operation once it stops being called for the specified debounce duration. Keep in mind that using DebounceExecutor introduces latency to the operation for at least the specified debounce duration. In most cases it should be used when the operation is expensive to execute or under high event rate or load. As a side effect, DebounceExecutor guarantees that at most one operation is executing at a time. Execute calls the function f if and only if Execute is not called again during the debounce interval. Context expiration cancels an operation. It returns ErrDebounced error if the given operation f was superseded by another Execute call. If Execute is called concurrently, the last invocation wins. When another operation is already executing, it returns ErrDebounced. Callers should handle ErrDebounced error to avoid breaking assumptions when running under another DebounceExecutor. As a side effect, it guarantees that at most one f is executing at a time. That is, it is safe to avoid locking if the state is mutated exclusively under the DebounceExecutor. WithClock returns a copy of the executor that uses the given clock. WithWait returns a copy of the executor that uses the given wait duration. It shares the underlying state and can be used to debounce operation with non-default wait duration. *DebounceExecutor : Executor func Debounce(t time.Duration) *DebounceExecutor func (*DebounceExecutor).WithClock(c *clock.Clock) *DebounceExecutor func (*DebounceExecutor).WithWait(t time.Duration) *DebounceExecutor
Executor is an executor for flaky operations. Execute executes a flaky operation f using the execution policy. *DebounceExecutor *RetryExecutor *ScheduleExecutor *WatchdogExecutor func Once() Executor func UntilPermanent() Executor func Watchdog(e Executor, s Schedule) *WatchdogExecutor func WithSchedule(e Executor, s Schedule) *ScheduleExecutor
Jitter is a function that, given a closed interval v, returns a random value on that interval. Backoff returns a new Backoff with jitter for the given interval. Jitter implements the JitterProvider interface. Schedule returns a new Schedule with jitter for the given interval. Jitter : JitterProvider func RandomJitter(f func(n int64) int64) Jitter func Jitter.Jitter() Jitter func JitterProvider.Jitter() Jitter
JitterInterval describes a closed jitter interval. The final jitter value for random number N is computed as N - L/Q where N ∈ (0; L] for L > 0 and N ∈ [L; 0) for L < 0. If L = 0 then the final jitter value is always zero. L is the length of the jitter interval. Q specifies 1/q quotient of the interval length to subtract from the random number. func Jitter.Backoff(b Backoff, v JitterInterval) Backoff func Jitter.Schedule(s Schedule, v JitterInterval) Schedule
JitterProvider provides a jitter for executing operations. ( JitterProvider) Jitter() Jitter Jitter
Op is an operation that is likely to fail. func (*DebounceExecutor).Execute(ctx context.Context, f Op) error func Executor.Execute(ctx context.Context, f Op) error func (*RetryExecutor).Execute(ctx context.Context, f Op) error func (*ScheduleExecutor).Execute(ctx context.Context, f Op) error func (*WatchdogExecutor).Execute(ctx context.Context, f Op) error
PermanentError indicates that a permanent error has been encountered during a retry attempt. Error implements the error interface. Internal returns whether the permanent error is internal. It is guaranteed that Executor’s Execute method does not return internal errors. Unwrap unwraps the underlying error. *PermanentError : error func AsPermanentError(err error) (*PermanentError, bool) func Internal(err error) *PermanentError func Permanent(err error) *PermanentError
RetryExecutor is an executor that retries executing an operation using the provided backoff. It allows executing operations that may succeed after a few attempts. Execute implements the Executor interface. WithClock returns a copy of the executor that uses the given clock. *RetryExecutor : Executor func Retry(b BackoffProvider) *RetryExecutor func (*RetryExecutor).WithClock(c *clock.Clock) *RetryExecutor
Schedule defines the schedule to use for WithSchedule. Next returns the next schedule time relative to now. If there is no schedule past the given time, it returns zero time or a value before now. github.com/robfig/cron/v3.ConstantDelaySchedule github.com/robfig/cron/v3.Schedule (interface) *github.com/robfig/cron/v3.SpecSchedule Schedule : github.com/robfig/cron/v3.Schedule func Midnight(d time.Duration, loc *time.Location) Schedule func Sleep(d time.Duration) Schedule func Until(s Schedule, t time.Time) Schedule func Jitter.Schedule(s Schedule, v JitterInterval) Schedule func Until(s Schedule, t time.Time) Schedule func Watchdog(e Executor, s Schedule) *WatchdogExecutor func WithSchedule(e Executor, s Schedule) *ScheduleExecutor func Jitter.Schedule(s Schedule, v JitterInterval) Schedule
ScheduleExecutor is an executor that restricts operation execution to the specified schedule. It allows executing operations that may only succeed at the given time. Execute implements the Executor interface. WithClock returns a copy of the executor that uses the given clock. *ScheduleExecutor : Executor func WithSchedule(e Executor, s Schedule) *ScheduleExecutor func (*ScheduleExecutor).WithClock(c *clock.Clock) *ScheduleExecutor
WatchdogExecutor is an executor that keeps executing an operation on schedule using the underlying executor until an error is returned or context expires. It allow monitoring a resource that should not fail. Execute implements the Executor interface. WithClock returns a copy of the executor that uses the given clock. *WatchdogExecutor : Executor func Watchdog(e Executor, s Schedule) *WatchdogExecutor func (*WatchdogExecutor).WithClock(c *clock.Clock) *WatchdogExecutor
Package-Level Functions (total 20, in which 17 are exported)
AsPermanentError attempts to extract PermanentError from err’s error chain.
Constant returns a constant backoff that uses nth duration for the arguments. It returns the last element if the attempt count is greater than the number of arguments. Passing no arguments is equivalent to no backoff.
Debounce returns a new DebounceExecutor instance for the given wait duration.
Exp2 returns an exponential backoff that returns base-2 exponential of failed attempts count times the given duration unit. Note that the backoff stops after wait duration reaches max positive value of time.Duration or once n is equal to math.MaxUint.
Internal marks an error as a permanent internal error. Executors unwrap internal errors prior to returning them.
IsPermanentError returns whether err’s error chain contains PermanentError.
Limit limits the number of retries for the given backoff. That is, it stops the backoff once retries counter reaches the given limit. Passing a limit of zero retries is equivalent to no backoff.
Midnight returns a repeated Schedule for the duration d since midnight in the given in location. If the location is nil, it defaults to UTC. Passing a non-positive duration is equivalent to not using a schedule.
Once returns a new executor that does not retry operations. That is, it executes the operation exactly once and returns the result.
Permanent marks an error as permanent. That is, returning permanent error from retry attempt would stop the retry process.
RandomJitter returns a Jitter function for function f that defaults to math/rand.Int63n if it is nil.
Retry returns a new executor that uses the backoff provider to retry operation execution. It attempts to execute f until a backoff function returns false, an attempt returns permanent error or a context expires. On failure it returns the last error encountered. It requests a new backoff function from provider for each Execute invocation.
Sleep returns a Schedule that delays execution for a fixed interval d. Passing a non-positive duration is equivalent to not using a schedule.
Until returns a schedule that stops at the given time. It allows defining the schedule for operations that should fail after the given time.
UntilPermanent returns a new executor that retries operations until either a permanent error or context expiration.
Watchdog executes an operation on the given schedule using the executor until an error is returned or the context expires. It allow monitoring a resource that should not fail. Note that it returns a nil error iff context expires. Otherwise an error from the executor indicates an operation failure. This design allows interrupting execution using the context but the tradeoff is that an error is discarded. That is mostly noticeable when the executor retries operations and a context expires after a failure. In that case the error would not be propagated to the watchdog user. Unlike a simple loop that executes the given executor and waits a certain amount of time, watchdog enforces the use of a configurable schedule.
WithSchedule restricts the executor to wait for the given scheduled time before executing an operation.
Package-Level Variables (total 3, all are exported)
ErrDebounced is an error that DebounceExecutor returns when an Execute call is superseded by another operation.
ErrNoNextSchedule is an error that is returned by ScheduleExecutor if there is no next scheduled time or it is before current time.
ErrScheduleDeadline is an error that is returned by ScheduleExecutor if scheduled time exceeds the context deadline.