Documentation
¶
Index ¶
- Constants
- Variables
- func ShouldRunLocalHour(tz string, hour int) bool
- func ShouldRunLocalTime(tz string, hour, minute int) bool
- type Job
- type Option
- type Schedule
- type Scheduler
- func (s *Scheduler) Active() int64
- func (s *Scheduler) Add(id string, when Schedule, job Job) error
- func (s *Scheduler) Idled() <-chan struct{}
- func (s *Scheduler) RunNext(ctx context.Context, id string, job Job) bool
- func (s *Scheduler) RunOnce(ctx context.Context, id string, job Job) bool
- func (s *Scheduler) Start(ctx context.Context)
- func (s *Scheduler) Supersede(ctx context.Context, id string, job Job) bool
Constants ¶
const ( // DefaultShutdownTimeout is how long Start waits for running jobs after its // ctx is done, unless WithShutdownTimeout sets another value. DefaultShutdownTimeout = 60 * time.Second // DefaultJobTimeout is the per-job timeout applied when the job's ctx has no // deadline, unless WithJobTimeout sets another value. DefaultJobTimeout = time.Hour )
Variables ¶
var ErrSuperseded error = ez.New(ez.ECANCELED, "scheduler: superseded", context.Canceled)
ErrSuperseded is the context cause seen by a job that was cancelled because Supersede queued a replacement for the same id. errors.Is(context.Cause(ctx), ErrSuperseded) and errors.Is(context.Cause(ctx), context.Canceled) both hold.
Functions ¶
func ShouldRunLocalHour ¶ added in v1.6.0
ShouldRunLocalHour returns true if the local time in tz is exactly hour:00.
func ShouldRunLocalTime ¶ added in v1.6.4
ShouldRunLocalTime returns true if the local time in tzName matches hour:minute exactly.
Types ¶
type Option ¶ added in v1.6.0
type Option func(*Scheduler)
Option configures the Scheduler. Pass options to New.
func WithJobTimeout ¶ added in v1.6.0
WithJobTimeout sets the per-job timeout applied when the job's ctx has no deadline. The timer starts when the job body is about to run, after any permit from WithLimit was acquired, so time spent waiting for a permit does not count. d <= 0 is ignored.
func WithLimit ¶ added in v1.12.0
WithLimit caps at n the number of jobs whose id starts with prefix that run at the same time, across RunOnce, Supersede, RunNext and recurring jobs. A job over the cap waits for a permit, still counts in Active, and gives up without running if its context is cancelled while waiting. New rejects an empty prefix, n < 1, a prefix given twice, and a prefix that is a prefix of another limit's prefix.
func WithLogger ¶ added in v1.6.0
WithLogger sets the logger. Nil => Noop logger.
func WithShutdownTimeout ¶ added in v1.6.0
WithShutdownTimeout sets how long Start waits for jobs to drain after its ctx is done. d <= 0 is ignored.
type Schedule ¶ added in v1.12.0
type Schedule struct {
// contains filtered or unexported fields
}
Schedule is an immutable description of the wall-clock minutes at which a recurring job is due. Build it with Every, Hourly or Daily. The zero value is invalid. A value can be reused for several ids.
func Daily ¶ added in v1.12.0
Daily returns a Schedule that is due once a day at hour:minute wall-clock time in loc. hour must be in 0..23, minute in 0..59 and loc non-nil. On a day where that local time does not exist (DST spring-forward) the schedule is not due; on a day where it occurs twice (DST fall-back) it is due at both instants. Invalid input yields a Schedule that Add rejects with an ez.EINVALID error.
func Every ¶ added in v1.12.0
Every returns a Schedule that is due at minute 0 of every hour and every d after it, in server-local time. d must be a whole number of minutes that divides one hour evenly (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30 or 60 minutes). Every(time.Hour) is equivalent to Hourly(0). An invalid d yields a Schedule that Add rejects with an ez.EINVALID error.
func Hourly ¶ added in v1.12.0
Hourly returns a Schedule that is due at each of the given minutes of every hour, in server-local time. At least one minute is required, each must be in 0..59 and none may repeat. Order does not matter. Invalid input yields a Schedule that Add rejects with an ez.EINVALID error.
type Scheduler ¶
type Scheduler struct {
// contains filtered or unexported fields
}
Scheduler runs recurring jobs on wall-clock minute boundaries and one-shot jobs on demand. Work is keyed by id: at most one invocation per id runs at a time, and each busy id holds at most one pending job that runs after the current one returns. Create it with New.
func New ¶
New creates a Scheduler with the given options. It returns an ez.EINVALID error when a WithLimit option has an empty prefix, a size below 1, a prefix given twice, or a prefix that is a prefix of another limit's prefix.
func (*Scheduler) Active ¶ added in v1.6.2
Active returns the number of ids with admitted work: running, or waiting for a permit from a WithLimit option. A pending job adds nothing to the count.
func (*Scheduler) Add ¶
Add registers job to run at the minute boundaries selected by when. It returns an ez.EINVALID error for an empty id, a nil job or an invalid Schedule, and an ez.ECONFLICT error when a recurring job with the same id is already registered; on error nothing is registered. Add may be called before or after Start. The id is shared with RunOnce, Supersede and RunNext: a due boundary is skipped while the id is busy.
Daily schedules follow wall time in their location: on a DST spring-forward day a nonexistent local time does not fire, and on a fall-back day a repeated local time fires at both instants.
func (*Scheduler) Idled ¶ added in v1.6.2
func (s *Scheduler) Idled() <-chan struct{}
Idled returns a channel that receives a value when the last busy id finishes and Active drops to zero. It has a buffer of one and sends never block, so a receiver may see one value for several idle transitions. It does not fire between a job and the pending job that follows it. Check Active after receiving, since new work may already have been admitted.
func (*Scheduler) RunNext ¶ added in v1.12.0
RunNext starts job under id now when id is idle. When id is busy it replaces the id's pending job with job and returns true without cancelling the current invocation; job starts after the current invocation returns. It returns false when id is empty, job is nil, ctx is already done, or the Scheduler is stopping. A pending job whose ctx is done by then is dropped.
func (*Scheduler) RunOnce ¶
RunOnce starts job under id now. It returns false without running anything when id is empty, job is nil, ctx is already done, the Scheduler is stopping, or id is busy; a busy id's pending job is left untouched.
func (*Scheduler) Start ¶
Start runs the minute engine and blocks until ctx is done. It sleeps until the next wall-clock minute boundary, runs the recurring jobs due at it, and repeats. It never fires immediately: the first boundary evaluated is the first one after Start is called.
A late wake, because the process was frozen or the clock jumped forward, catches up: every minute boundary between the last one handled and the clock is evaluated, and a registration due at any of them is admitted once. A due job whose id is still busy is skipped for that wake. Nothing is remembered across restarts, so minutes that pass while the process is not running are never replayed. If the clock is stepped back by a minute or more the engine follows it and evaluates those minutes again as they pass.
When ctx is done Start stops the Scheduler: nothing new is admitted, pending jobs are discarded, running jobs are cancelled with context.Canceled, and Start waits for them up to the shutdown timeout before returning. Jobs that ignore their context may outlive that wait. Call Start once; once it has returned, a later call returns immediately.
func (*Scheduler) Supersede ¶ added in v1.12.0
Supersede starts job under id now when id is idle. When id is busy it replaces the id's pending job with job, cancels the current invocation with cause ErrSuperseded and returns true without waiting; job starts after the current invocation returns. It returns false when id is empty, job is nil, ctx is already done, or the Scheduler is stopping.