Documentation
¶
Overview ¶
Package cron is the occurrence engine behind a deployment's schedule: the reference's 5-field POSIX cron dialect, matched literally against a wall clock in an IANA timezone.
Due, Next and Upcoming share one generator on purpose. The list a user reads in a deployment's upcoming_runs_at and the instant the scheduler actually fires come from the same walk, so they cannot disagree — plan 37 §3.1, and the property test in cron_test.go asserts it.
The dialect is a strict subset of what a general cron library accepts, which is why this is hand-rolled: seconds and year fields, the special characters L, W, # and ?, and predefined shortcuts like @daily are all excluded, so a library would need a rejection layer in front of it and would still not supply the two daylight-saving rules below.
Timezones ¶
The tzdata import is deliberate and belongs here rather than in a main. The server image is debian:stable-slim with ca-certificates and nothing else, so without an embedded database every non-UTC deployment would be refused at create time in the image and never in the test gate, whose host has a zoneinfo tree. Costing ~450 KB in the binary buys the guarantee that no binary or test can forget it.
Daylight saving ¶
A wall clock that does not exist on the spring-forward day is skipped; one that occurs twice on the fall-back day fires twice, as two distinct instants. Neither rule is published by the reference — both are registered inferences (plan 37 §8.1 entry 19) — and both are the highest-risk code here, because a wrong answer looks exactly like a right one.
Index ¶
Constants ¶
const SearchYears = 12
SearchYears bounds every walk. Twelve rather than a round four because "0 0 29 2 *" — the sparsest satisfiable expression — has an eight-year gap across 2100, which is not a leap year; a shorter bound would report a legal schedule as unsatisfiable (plan 37 §3.3).
Exported because the API refuses an expression with no occurrence inside it and logs how far it looked: the refusal is the reference's sentence, which says "the next year" (#540), and an operator reading why a sparse schedule was refused needs the bound actually searched.
Variables ¶
var ( ErrExpression = errors.New("invalid cron expression") ErrTimezone = errors.New("invalid timezone") )
ErrExpression and ErrTimezone are distinguishable because the API turns them into 400s naming different fields; a caller must not have to match strings.
Functions ¶
func Due ¶
Due returns every occurrence in (from, to], ascending. The lower bound is exclusive because the scheduler's watermark is the last occurrence it claimed; including it would re-select that one on every tick.
Types ¶
This section is empty.