Documentation
¶
Index ¶
Constants ¶
const ( // UnlimitedRetries disables the retry limit — the task retries forever // (until a permanent error or context cancellation). // Use with caution: set this explicitly to opt in. UnlimitedRetries = -1 // DefaultMaxRetries is used when MaxRetries is 0 (zero-value). DefaultMaxRetries = 3 )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BackoffConfig ¶ added in v0.5.0
BackoffConfig controls exponential backoff between retry attempts.
func DefaultBackoff ¶ added in v0.5.0
func DefaultBackoff() BackoffConfig
DefaultBackoff returns a sensible default backoff configuration.
func (*BackoffConfig) Duration ¶ added in v0.6.0
func (b *BackoffConfig) Duration(attempt int) time.Duration
Duration returns the backoff duration for the given 0-based attempt index.
When Max > 0, the result is capped at Max. When Max is 0 (no cap) and the computed duration overflows (e.g. after thousands of attempts with UnlimitedRetries), Duration clamps to math.MaxInt64.
type Matcher ¶ added in v0.6.0
type Matcher struct {
// contains filtered or unexported fields
}
Matcher checks whether an error matches a given pattern.
Two forms are supported:
- error value (sentinel): matched via errors.Is
- *T where T implements error: matched via errors.As
Examples:
NewMatcher(ErrTimeout) // sentinel → errors.Is NewMatcher((*net.OpError)(nil)) // pointer-to-type → errors.As
func NewMatcher ¶ added in v0.6.0
NewMatcher compiles an error pattern into a Matcher.
The errVal argument must be one of:
- an error value (for errors.Is matching)
- a pointer to an error type, i.e. *T where T implements error (for errors.As matching)
Panics if errVal is nil or an unsupported type.
type Option ¶ added in v0.6.0
type Option func(*taskConfig)
Option configures a Task. Use With* functions to create options.
func WithDelay ¶ added in v0.6.0
WithDelay delays the first execution by the given duration. For interval tasks: first tick fires after delay, then every interval. For one-shot tasks: execution starts after delay. Delay is independent of interval.
func WithLogger ¶ added in v0.6.0
WithLogger sets a custom logger for the task. Defaults to slog.Default().
func WithShutdown ¶ added in v0.6.0
func WithShutdown(fn ShutdownFunc) Option
WithShutdown registers a graceful shutdown hook for the task. The hook is called by Runner after all task goroutines have stopped.
func WithTimeout ¶ added in v0.6.0
WithTimeout sets a per-invocation timeout for the work function. Each call to work gets its own context with this deadline.
type RuleTracker ¶ added in v0.6.0
type RuleTracker struct {
// contains filtered or unexported fields
}
RuleTracker tracks retry attempts for a single TransientRule.
Each rule has its own independent budget. The tracker is created internally by Task from TransientRule.MaxRetries.
func NewRuleTracker ¶ added in v0.6.0
func NewRuleTracker(maxRetries int) *RuleTracker
NewRuleTracker creates a tracker with the given max retries.
MaxRetries semantics:
0 (zero-value) → DefaultMaxRetries (3). -1 (UnlimitedRetries) → no limit. >0 → exact limit.
func (*RuleTracker) Attempt ¶ added in v0.6.0
func (rt *RuleTracker) Attempt() int
Attempt returns the current attempt count.
func (*RuleTracker) Max ¶ added in v0.6.0
func (rt *RuleTracker) Max() int
Max returns the resolved max retries.
func (*RuleTracker) OnFailure ¶ added in v0.6.0
func (rt *RuleTracker) OnFailure() (int, bool)
OnFailure records a failure and returns the 0-based attempt index and whether the caller is allowed to retry.
Example with max=3:
1st call: attempt=0, ok=true 2nd call: attempt=1, ok=true 3rd call: attempt=2, ok=true 4th call: attempt=3, ok=false (budget exhausted)
func (*RuleTracker) Reset ¶ added in v0.6.0
func (rt *RuleTracker) Reset()
Reset sets the attempt counter back to zero (e.g. after healthy progress).
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner orchestrates N tasks. When any task returns a permanent error the runner cancels all remaining tasks and performs graceful shutdown.
Runner does NOT handle OS signals — pass a cancellable context (e.g. via signal.NotifyContext).
func NewRunner ¶
func NewRunner(opts RunnerOptions) *Runner
NewRunner creates a Runner with the given options.
func (*Runner) Wait ¶
Wait starts all tasks concurrently and blocks until they all finish. When any task returns an error, all other tasks are cancelled via ctx. After all goroutines finish, shutdown hooks are called in LIFO order (reverse of Add). The ctx passed in controls the lifetime — the runner does NOT listen for OS signals; use signal.NotifyContext in the caller.
type RunnerOptions ¶ added in v0.5.0
type RunnerOptions struct {
ShutdownTimeout time.Duration // default 30s
Logger *slog.Logger // nil = slog.Default()
}
RunnerOptions configures a Runner.
type ShutdownFunc ¶ added in v0.5.0
ShutdownFunc is called during graceful shutdown.
type Task ¶ added in v0.5.0
type Task struct {
// contains filtered or unexported fields
}
Task is a self-contained unit of work with interval, retry and backoff support. It can be used standalone (via Wait) or managed by a Runner.
Task is NOT safe for concurrent use — call Wait from a single goroutine. Runner handles this automatically (one goroutine per task).
func NewIntervalTask ¶ added in v0.6.0
func NewIntervalTask(name string, interval time.Duration, work WorkFunc, rules []TransientRule, opts ...Option) *Task
NewIntervalTask creates a task that runs on a ticker loop. If rules is nil — any error kills the task. If rules is provided — transient errors are retried per their configuration, permanent errors (no matching rule) kill the task.
Each TransientRule binds an error to its own retry budget and backoff curve. TransientRule.MaxRetries limits consecutive failures for that rule. When a tick completes successfully, all rule trackers reset — so intermittent failures separated by successful ticks never accumulate toward MaxRetries.
Panics if work is nil or interval <= 0. Panics if any rule has nil Err, unsupported Err type, or Backoff.Initial <= 0.
func NewOneShotTask ¶ added in v0.6.0
func NewOneShotTask(name string, work WorkFunc, rules []TransientRule, opts ...Option) *Task
NewOneShotTask creates a task that executes once. If rules is nil — no retries, any error is fatal. If rules is provided — transient errors are retried per their configuration.
Each TransientRule binds an error to its own retry budget and backoff curve. TransientRule.MaxRetries limits consecutive failures for that rule — the budget is never reset mid-execution for one-shot tasks.
Panics if work is nil. Panics if any rule has nil Err, unsupported Err type, or Backoff.Initial <= 0.
type TransientRule ¶ added in v0.6.0
type TransientRule struct {
// Err is the error to match.
// Must be an error value (for errors.Is) or a pointer to an error type (for errors.As).
// Passing nil or an unsupported type panics at construction time.
Err any
// MaxRetries limits consecutive retry attempts for this rule.
// 0 (zero-value) → DefaultMaxRetries (3) — safe default.
// -1 (UnlimitedRetries) → no limit — explicit opt-in.
// >0 → exact retry count.
MaxRetries int
Backoff BackoffConfig
}
TransientRule binds an error to its retry settings. Different errors can have different retry budgets and backoff curves.
The Err field accepts two forms:
- error value (sentinel): matched via errors.Is
- *T where T implements error: matched via errors.As
Examples:
{Err: ErrTimeout} // sentinel → errors.Is
{Err: (*net.OpError)(nil)} // pointer-to-type → errors.As