Documentation
¶
Overview ¶
Package scheduler provides a flexible framework for running recurring tasks concurrently.
The core of the package is the Scheduler interface, which manages the lifecycle of scheduled jobs. The basic unit of work is a Task, which can be adapted into a schedulable Tick. A Tick is a self-repeating job that determines its own next run time by returning a duration after each execution.
Usage ¶
Helpers like Every and After are provided to easily convert a simple Task into a Tick with common scheduling patterns:
- Every(d, task): Creates a drift-free Tick that runs at a fixed cadence of duration d, accounting for the task's own execution time.
- After(d, task): Creates a drifting Tick that waits for a fixed duration d after the previous run completes.
Example:
s := scheduler.New(context.Background())
defer s.Shutdown()
task := scheduler.TaskFn(func(context.Context) {
slog.Info("Tick!")
})
tick := scheduler.Every(2*time.Second, task)
s.Dispatch(tick)
// Let the scheduler run for a while.
time.Sleep(5 * time.Second)
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Scheduler ¶
type Scheduler interface {
// Context returns the scheduler's context. This context is cancelled when
// Shutdown is called. Users can select on this context's Done channel to
// coordinate with the scheduler's termination.
Context() context.Context
// Dispatch executes the given tick in a separate goroutine. The tick will
// run immediately and then repeat according to the duration it returns
// until the scheduler is shut down. Multiple ticks can be dispatched
// concurrently without blocking each other.
Dispatch(tick Tick)
// Shutdown gracefully stops the scheduler. It cancels the scheduler's context
// and waits for all its pending tasks to complete. Shutdown blocks until all
// dispatched goroutines have finished.
Shutdown()
}
Scheduler manages the non-blocking execution of Ticks at their intervals.
func New ¶
New creates a new Scheduler whose lifecycle is tied to the provided parent context. Cancelling this context will also cause the scheduler to shut down.
type Task ¶
type Task interface {
// Run executes the job. It accepts a context for cancellation and
// timeout control.
Run(ctx context.Context)
}
Task represents a unit of work to be executed in a scheduler's execution loop. Helpers like After and Every adapt a Task into a Tick.
type Tick ¶
type Tick interface {
// Run executes the job and returns the duration to wait before the next
// execution. It accepts a context that is cancelled when the scheduler
// is shut down.
//
// If the returned duration is zero or negative, the next run is scheduled
// immediately.
Run(ctx context.Context) time.Duration
}
Tick represents a unit of work that can be scheduled to run repeatedly.
func After ¶
After creates a drifting Tick that runs after a fixed delay. The scheduler waits for the full delay after the task has completed, so the effective cadence will vary based on the task's execution time.
func Every ¶
Every creates a drift-free Tick that runs at a fixed interval. The wrapper measures the Task's execution time and subtracts it from the specified interval, ensuring the task starts at a consistent cadence.
If a task's execution time exceeds the interval, the next run will start immediately.