Documentation
¶
Index ¶
Constants ¶
const MaxJobNameBytes = 256
MaxJobNameBytes caps the length of a job name. The cap exists to keep names cheap to log; it is not a security boundary on the name itself (names are opaque labels — sanitise them at any rendering call site).
Variables ¶
var ErrInvalidJobName = errors.New("cron: invalid job name")
ErrInvalidJobName is returned by Register when Name is empty or longer than MaxJobNameBytes.
var ErrNilJobRun = errors.New("cron: job Run is nil")
ErrNilJobRun is returned by Register when Run is nil. A nil Run would nil-pointer at execution time; rejecting at registration surfaces the bug at startup instead of inside a tick callback.
Functions ¶
Types ¶
type CronJob ¶
CronJob is the unit of scheduled work.
Run is invoked on every firing — its context is derived from the scheduler's parent context, so cancelling the scheduler cancels in-flight runs at the next yield point.
If Run returns an error it is forwarded to the scheduler's OnError callback (if set); otherwise it is silently dropped — jobs should not crash the process.
type Schedule ¶ added in v0.3.3
type Schedule struct {
// contains filtered or unexported fields
}
Schedule is a parsed cron expression with a public surface. It wraps the internal bitmask form so callers outside this package (notably the queue battery's Scheduler) can compute firing times without re-parsing or re-implementing a cron parser.
Schedule is immutable and safe for concurrent use.
func Parse ¶ added in v0.3.3
Parse parses a cron spec into a Schedule. It accepts the same syntax as ParseCron (standard 5-field plus @shortcuts, ranges, lists and steps). Unlike ParseCron — which returns the unexported internal form used by the in-process Scheduler — Parse returns a value other packages can hold and query via Next and Matches.
func (Schedule) Matches ¶ added in v0.3.3
Matches reports whether the schedule fires during the minute containing t.
func (Schedule) Next ¶ added in v0.3.3
Next returns the earliest firing time strictly after after. The result is minute-aligned (cron resolution is one minute) and carries after's location.
The search is bounded: cron fields cover at most the next few years, so a scan of a fixed horizon of minutes is guaranteed to find a match for any satisfiable expression. If no match exists within the horizon (only possible for an unsatisfiable spec such as Feb 30), Next returns the zero Time.
type Scheduler ¶
type Scheduler struct {
OnError func(jobName string, err error)
// contains filtered or unexported fields
}
Scheduler is a tiny in-process cron driver. It is intentionally minimal: no persistence, no distributed locks, no overlap protection across replicas. For single-instance background work it is sufficient; for horizontally scaled deployments use the DB-backed queue instead.
func NewScheduler ¶
func NewScheduler() *Scheduler
NewScheduler returns a Scheduler that wakes once per minute. The tick interval is a deliberate choice: cron resolution is one minute, and waking more often would burn CPU for no gain.
func (*Scheduler) Register ¶
Register adds a job. Returns an error if the spec is invalid, the name is empty or oversize, or Run is nil — callers catch typos at registration time rather than silently failing forever or nil-pointering at firing.
func (*Scheduler) RunOnce ¶
RunOnce fires every job whose schedule matches the given minute. Exported for tests that drive the tick manually instead of waiting on the wall clock; production code lets the loop call this.
Iterates under the lock without copying the slice. Jobs that mutate state (Register during tick) are safe because the mutex is held only for the read — new jobs appear on the next tick.
func (*Scheduler) Start ¶
Start begins the tick loop in a goroutine. Returns immediately. Idempotent: repeated Start calls are no-ops once the loop is running.
func (*Scheduler) Stop ¶
func (s *Scheduler) Stop()
Stop signals the loop to exit and blocks until it has. Safe to call multiple times, and safe to call before Start — if the loop was never launched there is nothing to wait for, so Stop returns immediately instead of blocking forever on a channel the loop never closes (which would hang graceful shutdown when boot aborts before Start runs).