Documentation
¶
Overview ¶
Package scheduler is a thin wrapper around robfig/cron/v3 that adds a JSONL ledger so each fired job leaves a durable record alongside the upgrade ledger (internal/agent/upgrade/ledger.go is its sibling shape — same Append+Tail pattern, different vocabulary).
Why a wrapper at all: outpost's first scheduled-work consumer (peer-coordinated backup) needs three things cron/v3 doesn't provide on its own — (1) a stable name → spec → fn registry that can be re-registered idempotently after a config reload, (2) panic recovery so a single misbehaving job can't take the daemon down, (3) a ledger so `outpost backup history` and the equivalent MCP resource can answer "when did the nightly backup last fire and did it succeed". A future cloudbox consumer can pull this package up to a sibling module under the umbrella; for now it lives here because outpost is the only caller and cloudbox's leader-only cron (peer-health sweep, retention) can be a bare time.Ticker until a second use case materializes.
Time zone: read once at Run() time from $TZ, falling back to time.Local. UTC normalisation was rejected because operators reason about "2 AM nightly" in local wall-clock time and we want "Europe/London" → "America/Los_Angeles" relocation to keep the schedule's human-meaning stable, not its instant.
Index ¶
Constants ¶
const ( StepFired = "fired" StepOK = "ok" StepFailed = "failed" )
Step names emitted by the wrap-fn in scheduler.go. Kept as constants so a CLI history-renderer doesn't string-match against loose literals.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type JobFunc ¶
JobFunc is the unit of scheduled work. The context is cancelled when Scheduler.Run's ctx is cancelled (so a long-running job can observe shutdown). A non-nil error is recorded in the ledger.
type Ledger ¶
type Ledger struct {
// contains filtered or unexported fields
}
Ledger is an append-only JSONL writer + bounded tail-reader. Path is fixed at construction; concurrent appends serialize through mu. An empty path disables writes silently (returns nil from Append).
func NewLedger ¶
NewLedger returns a Ledger backed by `path`. Doesn't touch the filesystem until the first Append.
func (*Ledger) Append ¶
func (l *Ledger) Append(entry LedgerEntry) error
Append writes one entry as a single JSON line. If `entry.At` is zero, it is filled with the current UTC time.
Errors writing the ledger are NOT fatal to the caller's flow — we would rather complete the scheduled job than abort it because we couldn't scribble a record. Callers can log Append's error but should continue.
func (*Ledger) LastByJob ¶
func (l *Ledger) LastByJob(job string) (LedgerEntry, error)
LastByJob returns the most recent ledger entry for `job`, or a zero entry + nil error if the job has never fired. Used by status surfaces to render "last ran at, succeeded/failed".
type LedgerEntry ¶
type LedgerEntry struct {
At time.Time `json:"at"`
Job string `json:"job,omitempty"`
Step string `json:"step"`
DurationMs int64 `json:"duration_ms,omitempty"`
Error string `json:"error,omitempty"`
Detail string `json:"detail,omitempty"`
}
LedgerEntry is one JSONL line in the scheduler history file. Shape intentionally parallels internal/agent/upgrade.LedgerEntry so a single tail-renderer can handle both files later (the upgrade surface uses ReleaseID where the scheduler uses Job).
type Scheduler ¶
type Scheduler struct {
// contains filtered or unexported fields
}
Scheduler runs named jobs on cron expressions. Construct via New; register every job before calling Run; Run blocks until ctx ends.
func New ¶
New returns a Scheduler that will write each fired job's outcome to ledgerPath. If ledgerPath is empty the ledger is silently disabled (useful for tests). Job functions receive ctx-cancellation when Run's ctx is cancelled.
func (*Scheduler) Ledger ¶
Ledger exposes the JSONL writer so callers can Tail it from CLI / MCP / HTTP surfaces (mirrors how upgrade.Worker exposes its upgrade.Ledger).
func (*Scheduler) Names ¶
Names returns the registered job names in arbitrary order. Useful for the "what's scheduled" admin view.
func (*Scheduler) NextRun ¶
NextRun returns the next scheduled fire time for name, or zero time if the name is unknown.
func (*Scheduler) Register ¶
Register adds (or replaces) a named job. spec is a cron expression (5-field "M H D M W" or one of cron/v3's descriptors: "@daily", "@hourly", "@every 1h", etc.). fn must be safe to call repeatedly and tolerate context cancellation.
Re-registering under the same name removes the previous entry first — supports the "outpost polls cloudbox for its policy list every 5 min and re-installs the cron entries" pattern without leaking duplicate fires.