Documentation
¶
Overview ¶
Package scheduler runs recurring background work.
It owns only the plumbing every background job needs — its own goroutine and ticker, panic recovery, an optional per-run timeout, uniform logging and a clean shutdown — so a task itself is just the work to do.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Scheduler ¶
type Scheduler struct {
// contains filtered or unexported fields
}
func New ¶
func New(appCtx *appContext.Context) *Scheduler
func (*Scheduler) Start ¶
func (s *Scheduler) Start()
Start launches one goroutine per enabled task. A task with a zero interval is skipped, which is how a feature disables its own background work through config.
type Task ¶
type Task interface {
// Name identifies the task in logs.
Name() string
// Interval is the delay between two runs. Zero disables the task.
Interval() time.Duration
// RunOnStart reports whether the first run happens at boot instead of waiting
// for the first tick.
RunOnStart() bool
// Timeout bounds a single run. Zero leaves it unbounded.
Timeout() time.Duration
// Run does the work. It must be idempotent: a task can run again after a failed
// or interrupted attempt.
Run(ctx context.Context) error
}
Task is a unit of recurring background work.
Scheduling policy and work sit in the same interface on purpose: the zero value of each knob already means "no option" — a zero interval disables the task, a zero timeout leaves the run unbounded, RunOnStart false waits for the first tick — so splitting them into optional interfaces would only have bought type assertions in the runner and awkward composition at every call site.