Documentation
¶
Overview ¶
Package cron is a cron scheduler.
Register jobs with Add or AddSchedule, then call Start. Stop cancels the loop and waits for in-flight jobs, capped by its context.
Specs use five fields. WithSeconds adds an optional leading seconds field; WithSeconds(true) requires six.
Subpackages ¶
- wrap: job wrappers (Recover, Timeout, SkipIfRunning, DelayIfRunning, Retry).
- workflow: DAG jobs with conditional dependencies.
- parserext: Quartz tokens (L, N#M, NL).
Index ¶
- Variables
- func Between(s Schedule, start, end time.Time) []time.Time
- func IsTriggered(s Schedule) bool
- func NextN(s Schedule, from time.Time, n int) []time.Time
- func ValidateSpec(spec string) error
- func ValidateSpecWith(spec string, p Parser) error
- type ConstantDelay
- type Cron
- func (c *Cron) Add(spec string, j Job, opts ...EntryOption) (EntryID, error)
- func (c *Cron) AddSchedule(s Schedule, j Job, opts ...EntryOption) (EntryID, error)
- func (c *Cron) Entries() iter.Seq[Entry]
- func (c *Cron) Entry(id EntryID) (Entry, bool)
- func (c *Cron) Remove(id EntryID) bool
- func (c *Cron) Running() bool
- func (c *Cron) Start() error
- func (c *Cron) Stop(ctx context.Context) error
- func (c *Cron) Trigger(id EntryID) error
- func (c *Cron) TriggerByName(name string) (int, error)
- type Entry
- type EntryID
- type EntryOption
- type EventJobComplete
- type EventJobStart
- type EventMissed
- type EventSchedule
- type HookDroppedRecorder
- type Job
- type JobCompleteHook
- type JobCompletedRecorder
- type JobFunc
- type JobMissedRecorder
- type JobScheduledRecorder
- type JobStartHook
- type JobStartedRecorder
- type MissedFirePolicy
- type MissedHook
- type Option
- func WithChain(wrappers ...Wrapper) Option
- func WithHookBuffer(n int) Option
- func WithHooks(hooks ...any) Option
- func WithJitter(max time.Duration) Option
- func WithLocation(loc *time.Location) Option
- func WithLogger(l *slog.Logger) Option
- func WithMaxConcurrent(n int) Option
- func WithMaxEntries(n int) Option
- func WithMissedFire(p MissedFirePolicy) Option
- func WithMissedTolerance(d time.Duration) Option
- func WithParser(p Parser) Option
- func WithRecorder(r any) Option
- func WithRetry(p RetryPolicy) Option
- func WithSecondsField() Option
- type ParseError
- type Parser
- type ParserOption
- type QueueDepthRecorder
- type RetryOption
- type RetryPolicy
- type Schedule
- type ScheduleHook
- type SpecAnalysis
- type SpecSchedule
- type StandardParser
- type Upcoming
- type Wrapper
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrCapacityReached = errors.New("cron: capacity reached") ErrAlreadyRunning = errors.New("cron: job already running") ErrJobTimeout = errors.New("cron: job timeout") ErrCronStopping = errors.New("cron: scheduler stopping") ErrEntryNotFound = errors.New("cron: entry not found") ErrSchedulerNotRunning = errors.New("cron: scheduler not running") ErrConcurrencyLimit = errors.New("cron: max concurrent reached") ErrSchedulerStopped = errors.New("cron: scheduler stopped") ErrNilJob = errors.New("cron: nil job") ErrNilSchedule = errors.New("cron: nil schedule") )
Functions ¶
func IsTriggered ¶
IsTriggered reports whether s came from TriggeredSchedule.
func ValidateSpec ¶
ValidateSpec returns nil iff spec parses with the standard parser.
func ValidateSpecWith ¶
ValidateSpecWith is ValidateSpec with a custom parser.
Types ¶
type ConstantDelay ¶
ConstantDelay is a fixed-interval Schedule. The interval has a 1s floor: sub-second durations fire every 1s. Whole-second intervals are aligned to the second boundary; fractional intervals (e.g. 1500ms) keep their exact period.
func (ConstantDelay) String ¶
func (d ConstantDelay) String() string
type Cron ¶
type Cron struct {
// contains filtered or unexported fields
}
Cron is a job scheduler. Construct one with New, register jobs, then Start.
func (*Cron) Add ¶
Add parses spec and registers j. It returns a *ParseError for invalid specs or ErrCapacityReached when WithMaxEntries rejects the registration.
func (*Cron) AddSchedule ¶
AddSchedule registers j against a programmatic Schedule.
func (*Cron) Remove ¶
Remove deregisters id. In-flight invocations continue; future automatic fires and future Trigger calls for id are rejected.
func (*Cron) Running ¶
Running reports whether the scheduler is running. It is observational; use Trigger's returned error for race-free dispatch decisions.
func (*Cron) Start ¶
Start launches the scheduler. It is idempotent while running and returns ErrSchedulerStopped after Stop has been called.
func (*Cron) Stop ¶
Stop halts the scheduler and waits for the loop, in-flight jobs and hook dispatcher to drain, capped by ctx. Returns ctx.Err() on timeout. Do not call it from inside a Job.
type Entry ¶
type Entry struct {
ID EntryID
Name string
Spec string // empty for AddSchedule entries
Schedule Schedule
Prev time.Time // zero if never fired
Next time.Time // zero if exhausted or TriggeredSchedule
}
Entry is the public read-only view of a scheduled item. Safe to copy.
type EntryOption ¶
type EntryOption func(*entryConfig)
EntryOption configures one entry.
func WithEntryChain ¶
func WithEntryChain(wrappers ...Wrapper) EntryOption
WithEntryChain installs per-entry wrappers inside the global chain.
func WithEntryRetry ¶
func WithEntryRetry(p RetryPolicy) EntryOption
WithEntryRetry overrides the global retry for one entry. A zero policy disables retry for that entry.
func WithTimeout ¶
func WithTimeout(d time.Duration) EntryOption
WithTimeout caps a Job's runtime with ErrJobTimeout as the cancel cause.
type EventJobComplete ¶
type EventJobComplete struct {
EntryID EntryID
Name string
ScheduledAt time.Time
FireAt time.Time
Duration time.Duration
Err error
}
EventJobComplete is emitted after the chain returns. Err is the chain result.
type EventJobStart ¶
EventJobStart is emitted just before the chain runs. ScheduledAt is the schedule-selected time; FireAt is the actual start time after jitter/queueing.
type EventMissed ¶
type EventMissed struct {
EntryID EntryID
Name string
ScheduledAt time.Time
Lateness time.Duration
Policy MissedFirePolicy
}
EventMissed is emitted for missed fires and MaxConcurrent rejections.
type EventSchedule ¶
EventSchedule is emitted when an entry is added or its next firing is recomputed after a fire.
type HookDroppedRecorder ¶
type HookDroppedRecorder interface{ HookDropped() }
type JobCompleteHook ¶
type JobCompleteHook interface{ OnJobComplete(EventJobComplete) }
type JobCompletedRecorder ¶
type JobFunc ¶
JobFunc adapts a function to Job.
Example ¶
package main
import (
"context"
"fmt"
"github.com/libtnb/cron"
)
func main() {
j := cron.JobFunc(func(ctx context.Context) error {
fmt.Println("hello")
return nil
})
_ = j.Run(context.Background())
}
Output: hello
type JobMissedRecorder ¶
type JobScheduledRecorder ¶
type JobScheduledRecorder interface{ JobScheduled(name string) }
type JobStartHook ¶
type JobStartHook interface{ OnJobStart(EventJobStart) }
type JobStartedRecorder ¶
type JobStartedRecorder interface{ JobStarted(name string) }
type MissedFirePolicy ¶
type MissedFirePolicy uint8
MissedFirePolicy controls behaviour when a fire is later than WithMissedTolerance. OnMissedFire fires regardless of policy.
const ( // MissedSkip ignores missed firings and resumes from the next // scheduled time. This is the default. MissedSkip MissedFirePolicy = iota // MissedRunOnce runs the job once for the most recent missed firing // (latest schedule.Next <= now), then resumes normally. MissedRunOnce )
func (MissedFirePolicy) String ¶
func (p MissedFirePolicy) String() string
type MissedHook ¶
type MissedHook interface{ OnMissedFire(EventMissed) }
type Option ¶
type Option func(*config)
Option configures a Cron.
func WithHookBuffer ¶
WithHookBuffer sets the hook event buffer size. Full buffers drop new events.
func WithHooks ¶
WithHooks installs async hook subscribers. Values may implement any subset of ScheduleHook, JobStartHook, JobCompleteHook, and MissedHook.
func WithJitter ¶
WithJitter adds a random delay in [0, max) to each firing.
func WithLocation ¶
WithLocation sets the default schedule timezone. Default is time.Local. Ignored when WithParser is set: a custom parser owns its timezone.
func WithLogger ¶
WithLogger sets the slog.Logger. Default slog.Default().
func WithMaxConcurrent ¶
WithMaxConcurrent caps in-flight jobs. Zero means unlimited.
func WithMaxEntries ¶
WithMaxEntries caps registered entries. Zero means unlimited.
func WithMissedFire ¶
func WithMissedFire(p MissedFirePolicy) Option
WithMissedFire selects the missed-fire policy. Default MissedSkip.
func WithMissedTolerance ¶
WithMissedTolerance sets the lateness threshold for "missed". Default 1s.
func WithParser ¶
WithParser installs a parser. It takes over timezone resolution, so WithLocation and WithSecondsField no longer apply.
func WithRecorder ¶
WithRecorder installs a metrics subscriber. Values may implement any subset of the recorder sub-interfaces.
func WithRetry ¶
func WithRetry(p RetryPolicy) Option
WithRetry sets the default RetryPolicy. Overridden by WithEntryRetry.
func WithSecondsField ¶ added in v0.2.2
func WithSecondsField() Option
WithSecondsField enables a leading seconds field in the built-in parser, so the common seconds + WithLocation case composes without WithParser.
type ParseError ¶
type ParseError struct {
Spec string
Field string // e.g. "minute"; "" if not applicable
Pos int // 0-based byte offset; -1 if unknown
Reason string
Err error
}
ParseError describes a failure parsing a cron specification.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error
type ParserOption ¶
type ParserOption func(*parserConfig)
ParserOption configures NewStandardParser.
func WithDefaultLocation ¶
func WithDefaultLocation(loc *time.Location) ParserOption
WithDefaultLocation sets the default timezone for specs without TZ=/CRON_TZ=. nil means time.Local.
func WithParserExt ¶
func WithParserExt(ext Parser) ParserOption
WithParserExt installs a pre-parse hook. Returning (nil, nil) falls through to the standard parser.
func WithSeconds ¶
func WithSeconds(strict ...bool) ParserOption
WithSeconds enables a leading seconds field. By default the parser accepts both 5- and 6-field specs (a 5-field spec is parsed with second=0). Pass true to require exactly 6 fields.
type QueueDepthRecorder ¶
type QueueDepthRecorder interface{ QueueDepth(n int) }
type RetryOption ¶
type RetryOption func(*RetryPolicy)
RetryOption configures a RetryPolicy built by Retry.
func RetryInitial ¶
func RetryInitial(d time.Duration) RetryOption
RetryInitial sets the first retry delay (default 1s).
func RetryJitterFrac ¶
func RetryJitterFrac(f float64) RetryOption
RetryJitterFrac is fractional uniform jitter (e.g. 0.1 = ±10%).
func RetryMaxDelay ¶
func RetryMaxDelay(d time.Duration) RetryOption
RetryMaxDelay caps backoff (zero = uncapped).
func RetryMultiplier ¶
func RetryMultiplier(m float64) RetryOption
RetryMultiplier is the per-attempt growth factor (<=1 stays constant).
type RetryPolicy ¶
type RetryPolicy struct {
MaxRetries int
Initial time.Duration
MaxDelay time.Duration
Multiplier float64
JitterFrac float64
}
RetryPolicy describes exponential backoff with optional jitter. MaxRetries == 0 disables retry; negative means unlimited until ctx cancellation. Fields are exported for config-driven assembly; use Retry(...) for programmatic construction.
func Retry ¶
func Retry(maxRetries int, opts ...RetryOption) RetryPolicy
Retry builds a RetryPolicy. maxRetries is the number of retries after the initial attempt; negative retries until ctx cancellation.
func (RetryPolicy) IsZero ¶
func (p RetryPolicy) IsZero() bool
IsZero is keyed only on MaxRetries so half-filled policies (e.g. only Initial set) don't produce a useless wrapper.
func (RetryPolicy) Wrapper ¶
func (p RetryPolicy) Wrapper() Wrapper
Wrapper returns a Wrapper that retries on error per p. Attempt errors are joined via errors.Join; ctx cancellation aborts, recording context.Cause so ErrJobTimeout / ErrCronStopping survive into the joined error.
type Schedule ¶
Schedule yields successive firing times. Next must return the first firing strictly after now, or zero when exhausted.
func TriggeredSchedule ¶
func TriggeredSchedule() Schedule
TriggeredSchedule never fires automatically. Combine with Trigger.
type ScheduleHook ¶
type ScheduleHook interface{ OnSchedule(EventSchedule) }
Hook sub-interfaces. WithHooks subscribers may implement any subset.
type SpecAnalysis ¶
type SpecAnalysis struct {
Spec string
Valid bool
Err error
IsTriggered bool
Descriptor string // "@every", "@hourly", ... or "" for 5/6-field specs
Interval time.Duration // set when Descriptor == "@every"
Location *time.Location // schedule timezone
NextRun time.Time // upcoming firing relative to the now passed in
}
SpecAnalysis is the result of AnalyzeSpec. Most fields are populated only when Valid is true.
func AnalyzeSpec ¶
func AnalyzeSpec(spec string, now time.Time) SpecAnalysis
AnalyzeSpec parses spec and returns a structured description.
func AnalyzeSpecWith ¶
func AnalyzeSpecWith(spec string, p Parser, now time.Time) SpecAnalysis
AnalyzeSpecWith is AnalyzeSpec with a custom parser.
type SpecSchedule ¶
type SpecSchedule struct {
// contains filtered or unexported fields
}
SpecSchedule is a parsed cron expression.
func (*SpecSchedule) Location ¶
func (s *SpecSchedule) Location() *time.Location
Location returns the evaluation timezone.
func (*SpecSchedule) LogValue ¶
func (s *SpecSchedule) LogValue() slog.Value
func (*SpecSchedule) Next ¶
func (s *SpecSchedule) Next(t time.Time) time.Time
Next returns the next firing after t, or zero if none is found.
The hour branch reconstructs the wall clock at the target hour instead of adding an absolute (h-hour)*time.Hour, which would overshoot a DST spring-forward gap and skip the day. The minute/second branches keep their absolute jumps: they never straddle a whole-hour DST boundary, and stepping through the repeated hour on fall-back keeps both firings observable.
type StandardParser ¶
type StandardParser struct {
// contains filtered or unexported fields
}
StandardParser is stateless and concurrent-safe.
func NewStandardParser ¶
func NewStandardParser(opts ...ParserOption) *StandardParser
NewStandardParser handles 5/6-field specs, descriptors, and TZ prefixes.
type Wrapper ¶
Wrapper decorates a Job.
func Chain ¶
Chain composes wrappers so the first wraps outermost.
Example ¶
package main
import (
"context"
"fmt"
"github.com/libtnb/cron"
)
func main() {
mk := func(name string) cron.Wrapper {
return func(j cron.Job) cron.Job {
return cron.JobFunc(func(ctx context.Context) error {
fmt.Println("enter", name)
err := j.Run(ctx)
fmt.Println("leave", name)
return err
})
}
}
core := cron.JobFunc(func(ctx context.Context) error {
fmt.Println("run core")
return nil
})
_ = cron.Chain(mk("outer"), mk("inner"))(core).Run(context.Background())
}
Output: enter outer enter inner run core leave inner leave outer
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
contrib
|
|
|
otel
module
|
|
|
prometheus
module
|
|
|
coordination
|
|
|
postgres
module
|
|
|
redis
module
|
|
|
examples
|
|
|
hello
command
|
|
|
quartz
command
|
|
|
seconds
command
|
|
|
slog
command
|
|
|
workflow
command
|
|
|
internal
|
|
|
heap
Package heap provides a typed min-heap with addressable items.
|
Package heap provides a typed min-heap with addressable items. |
|
parsecache
Package parsecache memoises parser results and never evicts.
|
Package parsecache memoises parser results and never evicts. |
|
Package parserext provides optional cron parser extensions.
|
Package parserext provides optional cron parser extensions. |
|
Package workflow runs DAGs of cron.Jobs.
|
Package workflow runs DAGs of cron.Jobs. |
|
Package wrap supplies Job decorators.
|
Package wrap supplies Job decorators. |