Documentation
¶
Index ¶
- Constants
- Variables
- func ErrScheduleInvalid(reason string) result.Error
- func ErrTriggerInvalid(reason string) result.Error
- type ConcurrencyPolicy
- type CronJobDefinition
- type DefaultScheduleProvider
- type DurationJobDefinition
- type DurationRandomJobDefinition
- type Execution
- type Job
- type JobDefinition
- type JobDescriptorOption
- func WithConcurrent() JobDescriptorOption
- func WithContext(ctx context.Context) JobDescriptorOption
- func WithLimitedRuns(limitedRuns uint) JobDescriptorOption
- func WithName(name string) JobDescriptorOption
- func WithStartAt(startAt time.Time) JobDescriptorOption
- func WithStartImmediately() JobDescriptorOption
- func WithStopAt(stopAt time.Time) JobDescriptorOption
- func WithTags(tags ...string) JobDescriptorOption
- func WithTask(handler any, params ...any) JobDescriptorOption
- type JobHandler
- type JobHandlerOption
- type MisfirePolicy
- type OneTimeJobDefinition
- type Run
- type RunAbandonedEvent
- type RunFailedEvent
- type RunFilter
- type RunStatus
- type Schedule
- type ScheduleFilter
- type ScheduleManager
- type ScheduleSpec
- type Scheduler
- type TriggerKind
- type TriggerSpec
Constants ¶
const ( ErrCodeScheduleNotFound = 2700 ErrCodeScheduleExists = 2701 ErrCodeScheduleDisabled = 2702 ErrCodeTriggerInvalid = 2703 ErrCodeJobNotRegistered = 2704 ErrCodeStoreDisabled = 2705 ErrCodeScheduleInvalid = 2706 )
Response codes for cron API errors (2700-2799).
const ( // EventTypeRunFailed is published when a run finishes failed: handler // error, panic, or per-run timeout. EventTypeRunFailed = "vef.cron.run.failed" // EventTypeRunAbandoned is published when the recovery sweep marks a // running row abandoned because its node stopped heartbeating. EventTypeRunAbandoned = "vef.cron.run.abandoned" )
Cron store event topics. Both are best-effort operational notifications published outside any transaction on the default event route — subscribe for alerting; never drive correctness from them (the run journal is the durable truth).
const ( // MinInterval is the smallest fixed rate an interval trigger accepts. MinInterval = time.Second // DefaultTimezone is the deterministic zone used when a cron trigger does // not name one explicitly. Durable schedules must never depend on a node's // process-local timezone. DefaultTimezone = "UTC" // MaxDurationMilliseconds is the largest whole-millisecond count a // time.Duration can represent; interval and timeout inputs beyond it // cannot round-trip through Go durations without wraparound. MaxDurationMilliseconds = int64((1<<63 - 1) / time.Millisecond) )
Variables ¶
var ( ErrScheduleNotFound = result.Err( i18n.T("cron_schedule_not_found"), result.WithCode(ErrCodeScheduleNotFound), ) ErrScheduleExists = result.Err( i18n.T("cron_schedule_exists"), result.WithCode(ErrCodeScheduleExists), ) ErrScheduleDisabled = result.Err( i18n.T("cron_schedule_disabled"), result.WithCode(ErrCodeScheduleDisabled), ) ErrJobNotRegistered = result.Err( i18n.T("cron_job_not_registered"), result.WithCode(ErrCodeJobNotRegistered), ) ErrStoreDisabled = result.Err( i18n.T("cron_store_disabled"), result.WithCode(ErrCodeStoreDisabled), ) )
Predefined cron API errors. These are business errors and keep the default HTTP 200 status; the failure is carried by the body code.
var ( // ErrJobNameRequired indicates job name is required. ErrJobNameRequired = errors.New("job name is required") // ErrJobTaskHandlerRequired indicates job task handler is required. ErrJobTaskHandlerRequired = errors.New("job task handler is required") // ErrJobTaskHandlerMustFunc indicates job task handler must be a function. ErrJobTaskHandlerMustFunc = errors.New("job task handler must be a function") )
var ( // ErrTriggerKindUnknown indicates a kind outside the TriggerKind vocabulary. ErrTriggerKindUnknown = errors.New("unknown trigger kind") // ErrTriggerExprRequired indicates a cron trigger without an expression. ErrTriggerExprRequired = errors.New("cron trigger requires an expression") // ErrTriggerExprInvalid indicates an unparsable cron expression. ErrTriggerExprInvalid = errors.New("invalid cron expression") // ErrTriggerTimezoneInvalid indicates an unloadable IANA timezone. ErrTriggerTimezoneInvalid = errors.New("invalid trigger timezone") // ErrTriggerFieldsConflict indicates fields that do not belong to the // selected trigger kind. ErrTriggerFieldsConflict = errors.New("trigger fields conflict with its kind") // ErrTriggerIntervalTooShort indicates a fixed rate below MinInterval. ErrTriggerIntervalTooShort = errors.New("trigger interval too short") // ErrTriggerIntervalTooLong indicates milliseconds outside time.Duration. ErrTriggerIntervalTooLong = errors.New("trigger interval exceeds the supported duration") // ErrTriggerFireTimeRequired indicates a one-shot trigger without a fire time. ErrTriggerFireTimeRequired = errors.New("one-shot trigger requires a fire time") )
TriggerSpec.Validate sentinels. The store's ScheduleManager wraps them into the outward ErrTriggerInvalid; they stay assertable for direct spec users.
Functions ¶
func ErrScheduleInvalid ¶ added in v0.40.0
ErrScheduleInvalid builds the spec-validation error for non-trigger faults (name, window, timeout, params, policy vocabulary), carrying the concrete reason. errors.Is matches through the shared code.
func ErrTriggerInvalid ¶ added in v0.40.0
ErrTriggerInvalid builds the trigger-validation error carrying the concrete reason. errors.Is matches the sentinel semantics through the shared code.
Types ¶
type ConcurrencyPolicy ¶ added in v0.40.0
type ConcurrencyPolicy string
ConcurrencyPolicy decides whether a fire may start while a previous run of the same schedule is still executing.
const ( // ConcurrencyForbid suppresses regular and manual fires and journals them // as skipped. Recovery requests remain pending until the active run ends. // The default. ConcurrencyForbid ConcurrencyPolicy = "forbid" // ConcurrencyAllow lets runs of the same schedule overlap. ConcurrencyAllow ConcurrencyPolicy = "allow" )
type CronJobDefinition ¶
type CronJobDefinition struct {
// contains filtered or unexported fields
}
CronJobDefinition defines a job using standard cron expression syntax. It supports both standard 5-field and extended 6-field (with seconds) cron expressions.
func NewCronJob ¶
func NewCronJob(expression string, withSeconds bool, options ...JobDescriptorOption) *CronJobDefinition
NewCronJob creates a new cron-based job definition using cron expression syntax. Set withSeconds to true if the expression includes seconds (6 fields), false for standard 5-field format.
type DefaultScheduleProvider ¶ added in v0.40.0
type DefaultScheduleProvider interface {
// DefaultSchedule returns the schedule to seed.
DefaultSchedule() ScheduleSpec
}
DefaultScheduleProvider is an optional JobHandler capability: a handler shipping a default schedule. The store seeds it at boot when no schedule of that name exists yet — operator changes are never overwritten. The spec's Name falls back to the job name.
type DurationJobDefinition ¶
type DurationJobDefinition struct {
// contains filtered or unexported fields
}
DurationJobDefinition defines a job that runs repeatedly at fixed intervals. The interval is specified as a time.Duration.
func NewDurationJob ¶
func NewDurationJob(interval time.Duration, options ...JobDescriptorOption) *DurationJobDefinition
NewDurationJob creates a new duration-based job definition that runs at fixed intervals.
type DurationRandomJobDefinition ¶
type DurationRandomJobDefinition struct {
// contains filtered or unexported fields
}
DurationRandomJobDefinition defines a job that runs at random intervals. The interval is randomly chosen between MinInterval and MaxInterval for each execution.
func NewDurationRandomJob ¶
func NewDurationRandomJob(minInterval, maxInterval time.Duration, options ...JobDescriptorOption) *DurationRandomJobDefinition
NewDurationRandomJob creates a new random duration job definition. The job will execute with a random interval between minInterval and maxInterval for each run.
type Execution ¶ added in v0.40.0
type Execution struct {
// RunID is the journal record's identifier, for run-scoped correlation.
// A Recover re-fire is a fresh run with a fresh RunID.
RunID string
// ScheduleID and ScheduleName identify the schedule that fired.
ScheduleID string
ScheduleName string
// JobName is the handler's own registered name.
JobName string
// ScheduledAt is the logical fire time; a catch-up fire executes later
// than it.
ScheduledAt time.Time
// Params is the schedule's params column, verbatim.
Params json.RawMessage
}
Execution describes the run a JobHandler is executing: the identity of the run and its schedule, the logical fire time, and the schedule's params. It is a read-only view — the journal record itself stays engine-owned.
func (Execution) BindParams ¶ added in v0.40.0
BindParams decodes the schedule's params into v; absent params leave v untouched.
type Job ¶
type Job interface {
// ID returns the job's unique identifier as a string.
ID() string
// LastRun returns the time when the job was last executed.
LastRun() (time.Time, error)
// Name returns the human-readable name assigned to the job.
Name() string
// NextRun returns the time when the job is next scheduled to run.
NextRun() (time.Time, error)
// NextRuns returns the specified number of future scheduled run times.
NextRuns(count int) ([]time.Time, error)
// RunNow executes the job immediately without affecting its regular schedule.
// This respects all job and scheduler limits and may affect future scheduling
// if the job has run limits configured.
RunNow() error
// Tags returns the list of tags associated with the job for grouping and filtering.
Tags() []string
}
Job represents a scheduled task in the cron system. It provides methods to inspect and control individual job instances.
type JobDefinition ¶
type JobDefinition interface {
// contains filtered or unexported methods
}
JobDefinition defines how a job should be scheduled and executed. Implementations specify different scheduling strategies (cron, duration, one-time, etc.).
type JobDescriptorOption ¶
type JobDescriptorOption func(*jobDescriptor)
JobDescriptorOption is a function type for configuring job descriptors using the options pattern.
func WithConcurrent ¶
func WithConcurrent() JobDescriptorOption
WithConcurrent allows the job to run concurrently with other instances of itself. By default, jobs run in singleton mode (no concurrent execution).
func WithContext ¶
func WithContext(ctx context.Context) JobDescriptorOption
WithContext associates a context with the job for cancellation support.
func WithLimitedRuns ¶
func WithLimitedRuns(limitedRuns uint) JobDescriptorOption
WithLimitedRuns limits the job to run only the specified number of times.
func WithName ¶
func WithName(name string) JobDescriptorOption
WithName assigns a human-readable name to the job.
func WithStartAt ¶
func WithStartAt(startAt time.Time) JobDescriptorOption
WithStartAt specifies when the job should start its schedule.
func WithStartImmediately ¶
func WithStartImmediately() JobDescriptorOption
WithStartImmediately makes the job start immediately when the scheduler starts.
func WithStopAt ¶
func WithStopAt(stopAt time.Time) JobDescriptorOption
WithStopAt specifies when the job should stop running.
func WithTags ¶
func WithTags(tags ...string) JobDescriptorOption
WithTags assigns tags to the job for grouping and bulk operations.
func WithTask ¶
func WithTask(handler any, params ...any) JobDescriptorOption
WithTask sets the handler function and its parameters for the job.
type JobHandler ¶ added in v0.40.0
type JobHandler interface {
// Name uniquely identifies the job.
Name() string
// Execute runs one fire. The context carries cancellation (graceful
// shutdown, per-run timeout); a returned error journals the run as
// failed.
Execute(ctx context.Context, execution Execution) error
}
JobHandler executes one named, durable job. Register implementations with vef.ProvideCronJobHandler — exactly one handler per job name; schedules reference the name as their JobName. A fire is claimed by at most one node, but a crashed run re-fires when Schedule.Recover is set, so handlers should be idempotent.
func NewJobHandler ¶ added in v0.40.0
func NewJobHandler(name string, execute func(ctx context.Context, execution Execution) error, opts ...JobHandlerOption) JobHandler
NewJobHandler adapts a function to a JobHandler.
func NewTypedJobHandler ¶ added in v0.40.0
func NewTypedJobHandler[P any](name string, execute func(ctx context.Context, params P) error, opts ...JobHandlerOption) JobHandler
NewTypedJobHandler adapts a typed function to a JobHandler: the schedule's params are decoded into P before the function runs; a decode failure journals the run as failed without invoking it.
type JobHandlerOption ¶ added in v0.40.0
type JobHandlerOption func(*jobHandlerConfig)
JobHandlerOption configures a handler built by NewJobHandler or NewTypedJobHandler.
func WithDefaultSchedule ¶ added in v0.40.0
func WithDefaultSchedule(spec ScheduleSpec) JobHandlerOption
WithDefaultSchedule ships a default schedule with the handler; the store seeds it at boot when absent (see DefaultScheduleProvider).
type MisfirePolicy ¶ added in v0.40.0
type MisfirePolicy string
MisfirePolicy decides what happens to fire times that were missed for longer than the configured misfire threshold (downtime, paused schedule, no free executor). Whichever policy applies, occurrences that will never run are journaled as a single missed run covering the whole gap.
const ( // MisfireFireNow runs one catch-up fire immediately and resumes the // regular sequence from now. The default. MisfireFireNow MisfirePolicy = "fire_now" // MisfireSkip advances to the next future fire without running. MisfireSkip MisfirePolicy = "skip" )
type OneTimeJobDefinition ¶
type OneTimeJobDefinition struct {
// contains filtered or unexported fields
}
OneTimeJobDefinition defines a job that runs once at specified times. It supports running immediately, at a single time, or at multiple specific times.
func NewOneTimeJob ¶
func NewOneTimeJob(times []time.Time, options ...JobDescriptorOption) *OneTimeJobDefinition
NewOneTimeJob creates a new one-time job definition with the specified execution times. If times is empty, the job will run immediately. If it contains one time, the job runs once at that time. If it contains multiple times, the job will run at each specified time.
type Run ¶ added in v0.40.0
type Run struct {
orm.BaseModel `bun:"table:crn_run,alias:cr"`
orm.CreationAuditedModel
ScheduleID string `json:"scheduleId" bun:"schedule_id"`
ScheduleName string `json:"scheduleName" bun:"schedule_name"`
JobName string `json:"jobName" bun:"job_name"`
// ScheduledAtUnixMs is the logical fire time; a catch-up fire starts later
// than it. It is deliberately not unique: manual and recovery fires may
// legitimately share one instant.
ScheduledAtUnixMs int64 `json:"scheduledAtUnixMs" bun:"scheduled_at_unix_ms"`
ClaimedAtUnixMs int64 `json:"claimedAtUnixMs" bun:"claimed_at_unix_ms"`
Status RunStatus `json:"status" bun:"status"`
// NodeID identifies the executing node; empty on rows that never
// executed (missed, skipped).
NodeID string `json:"nodeId" bun:"node_id"`
StartedAtUnixMs *int64 `json:"startedAtUnixMs,omitempty" bun:"started_at_unix_ms"`
FinishedAtUnixMs *int64 `json:"finishedAtUnixMs,omitempty" bun:"finished_at_unix_ms"`
DurationMs int64 `json:"durationMs" bun:"duration_ms"`
// HeartbeatAtUnixMs is the executor's liveness signal, renewed while the
// run executes; a stale heartbeat turns the run abandoned.
HeartbeatAtUnixMs *int64 `json:"heartbeatAtUnixMs,omitempty" bun:"heartbeat_at_unix_ms"`
// Error is the failure message, truncated; empty on success.
Error string `json:"error,omitempty" bun:"error"`
// MissedCount is the number of occurrences a missed row covers.
MissedCount int `json:"missedCount,omitempty" bun:"missed_count"`
}
Run is the journal record of one fire: its logical time, execution window, executing node, and outcome. Rows survive schedule deletion — ScheduleName and JobName are denormalized for that reason.
type RunAbandonedEvent ¶ added in v0.40.0
type RunAbandonedEvent struct {
RunID string `json:"runId"`
ScheduleName string `json:"scheduleName"`
JobName string `json:"jobName"`
// ScheduledAtUnixMs is the run's logical fire time.
ScheduledAtUnixMs int64 `json:"scheduledAtUnixMs"`
// NodeID identifies the node that stopped heartbeating.
NodeID string `json:"nodeId"`
}
RunAbandonedEvent reports one abandoned run. Whether it re-fires is the schedule's Recover setting.
func NewRunAbandonedEvent ¶ added in v0.40.0
func NewRunAbandonedEvent(run *Run) *RunAbandonedEvent
NewRunAbandonedEvent creates a run-abandoned event from the journal record.
func (*RunAbandonedEvent) EventType ¶ added in v0.40.0
func (*RunAbandonedEvent) EventType() string
EventType implements event.Event.
type RunFailedEvent ¶ added in v0.40.0
type RunFailedEvent struct {
RunID string `json:"runId"`
ScheduleName string `json:"scheduleName"`
JobName string `json:"jobName"`
// ScheduledAtUnixMs is the run's logical fire time.
ScheduledAtUnixMs int64 `json:"scheduledAtUnixMs"`
// NodeID identifies the node that executed the run.
NodeID string `json:"nodeId"`
// Error is the journaled failure message.
Error string `json:"error"`
}
RunFailedEvent reports one failed run.
func NewRunFailedEvent ¶ added in v0.40.0
func NewRunFailedEvent(run *Run) *RunFailedEvent
NewRunFailedEvent creates a run-failed event from the journal record.
func (*RunFailedEvent) EventType ¶ added in v0.40.0
func (*RunFailedEvent) EventType() string
EventType implements event.Event.
type RunFilter ¶ added in v0.40.0
type RunFilter struct {
// ScheduleName matches runs of one schedule.
ScheduleName string
// JobName matches runs of one job.
JobName string
// Statuses matches any of the given statuses.
Statuses []RunStatus
// Since and Until bound the logical fire time (inclusive since,
// exclusive until).
Since *time.Time
Until *time.Time
// Limit caps the result; zero resolves to 100, the cap is 1000.
Limit int
}
RunFilter narrows ListRuns; zero values match everything.
type RunStatus ¶ added in v0.40.0
type RunStatus string
RunStatus is the lifecycle state of one journaled run.
const ( // RunRunning marks a claimed fire that is executing (or about to). RunRunning RunStatus = "running" // RunSucceeded marks a run whose handler returned nil. RunSucceeded RunStatus = "succeeded" // RunFailed marks a run whose handler returned an error, panicked, or // exceeded its timeout. RunFailed RunStatus = "failed" // RunMissed records occurrences that misfire handling decided will never // run; one row covers a whole catch-up gap (see MissedCount). RunMissed RunStatus = "missed" // RunSkipped records a fire suppressed by ConcurrencyForbid. RunSkipped RunStatus = "skipped" // RunAbandoned marks a running row whose executor stopped heartbeating; // schedules with Recover set re-fire it. RunAbandoned RunStatus = "abandoned" // RunCanceled marks a run interrupted by graceful shutdown. RunCanceled RunStatus = "canceled" )
func (RunStatus) IsTerminal ¶ added in v0.40.0
IsTerminal reports whether the status is final.
type Schedule ¶ added in v0.40.0
type Schedule struct {
orm.BaseModel `bun:"table:crn_schedule,alias:cs"`
orm.FullAuditedModel
// Name uniquely identifies the schedule and is the management key.
Name string `json:"name" bun:"name"`
// JobName references the JobHandler that executes the fires.
JobName string `json:"jobName" bun:"job_name"`
Kind TriggerKind `json:"kind" bun:"kind"`
Expr string `json:"expr" bun:"expr"`
Timezone string `json:"timezone" bun:"timezone"`
EveryMs int64 `json:"everyMs" bun:"every_ms"`
FireAtUnixMs *int64 `json:"fireAtUnixMs,omitempty" bun:"fire_at_unix_ms"`
// StartsAtUnixMs and EndsAtUnixMs bound the fire window; either may be nil.
// StartsAtUnixMs also anchors the fixed-rate phase of interval triggers.
StartsAtUnixMs *int64 `json:"startsAtUnixMs,omitempty" bun:"starts_at_unix_ms"`
EndsAtUnixMs *int64 `json:"endsAtUnixMs,omitempty" bun:"ends_at_unix_ms"`
AnchorAtUnixMs int64 `json:"anchorAtUnixMs" bun:"anchor_at_unix_ms"`
// Params is delivered verbatim to the handler on every run.
Params json.RawMessage `json:"params,omitempty" bun:"params,type:jsonb,nullzero"`
MisfirePolicy MisfirePolicy `json:"misfirePolicy" bun:"misfire_policy"`
ConcurrencyPolicy ConcurrencyPolicy `json:"concurrencyPolicy" bun:"concurrency_policy"`
// Recover re-fires a run that did not complete: abandoned mid-execution
// (its node stopped heartbeating) or canceled by graceful shutdown.
// Recovery makes delivery at-least-once; the handler must be idempotent.
//
// The re-fire is immediate and unlimited: there is no backoff and no
// attempt ceiling, so a job that reliably kills the node executing it
// produces a cluster-wide retry loop. Enable it for work whose failure
// mode is the node, not the job.
Recover bool `json:"recover" bun:"recover"`
// TimeoutMs bounds one run; zero inherits vef.cron.store.run_timeout.
TimeoutMs int64 `json:"timeoutMs" bun:"timeout_ms"`
// IsEnabled is operator-owned: Pause clears it, Resume restores it. The
// engine only claims enabled schedules.
IsEnabled bool `json:"isEnabled" bun:"is_enabled"`
// NextFireAtUnixMs is the next due fire the engine will claim; nil when the
// trigger yields no further occurrence. Pausing preserves the cursor
// rather than clearing it — claiming filters on IsEnabled anyway, and
// keeping it is what lets Resume hand the paused gap to the misfire
// policy instead of silently dropping it.
NextFireAtUnixMs *int64 `json:"nextFireAtUnixMs,omitempty" bun:"next_fire_at_unix_ms"`
// LastFireAtUnixMs records the most recent claimed fire's logical time —
// an occurrence that produced a run, including one journaled as skipped
// because a previous run was still executing. Occurrences accounted as
// missed (the misfire gap) never advance it, so a schedule idle through
// downtime keeps the last time it actually reached the journal as a fire.
LastFireAtUnixMs *int64 `json:"lastFireAtUnixMs,omitempty" bun:"last_fire_at_unix_ms"`
}
Schedule is one persisted trigger: when to fire which job, with which params, under which policies. The trigger columns mirror TriggerSpec; NextFireAtUnixMs is the scheduling state the store engine claims and advances. A nil NextFireAtUnixMs on an enabled schedule means the trigger yields no further occurrence (a completed one-shot, an expired window).
func (*Schedule) Trigger ¶ added in v0.40.0
func (s *Schedule) Trigger() TriggerSpec
Trigger reconstructs the spec form of the schedule's trigger columns. The epoch preserves the one-shot instant across timezone folds.
type ScheduleFilter ¶ added in v0.40.0
type ScheduleFilter struct {
// JobName matches schedules of one job.
JobName string
// Enabled matches by enablement when non-nil.
Enabled *bool
}
ScheduleFilter narrows List; zero values match everything.
type ScheduleManager ¶ added in v0.40.0
type ScheduleManager interface {
// Create validates and persists a new schedule. The trigger must be
// structurally sound and the job name registered on this node; a taken
// name fails with ErrScheduleExists.
Create(ctx context.Context, spec ScheduleSpec) (*Schedule, error)
// Update reshapes the named schedule to the spec — including a rename
// when the spec carries a different, untaken name. Trigger or window
// changes recompute the next fire.
Update(ctx context.Context, name string, spec ScheduleSpec) (*Schedule, error)
// Delete removes the schedule. Journaled runs are kept — they carry the
// schedule and job names denormalized.
Delete(ctx context.Context, name string) error
// Pause stops fire claiming until Resume; running fires are unaffected.
Pause(ctx context.Context, name string) error
// Resume re-enables the schedule. Occurrences missed while paused are
// handled by the schedule's misfire policy: MisfireFireNow runs one
// catch-up immediately, MisfireSkip waits for the next regular fire.
Resume(ctx context.Context, name string) error
// TriggerNow persists one independent immediate fire request (single node,
// journaled, concurrency policy respected) without moving the regular
// trigger cursor. A paused schedule fails with ErrScheduleDisabled.
TriggerNow(ctx context.Context, name string) error
// Get returns the named schedule, or ErrScheduleNotFound.
Get(ctx context.Context, name string) (*Schedule, error)
// List returns schedules matching the filter, ordered by name.
List(ctx context.Context, filter ScheduleFilter) ([]Schedule, error)
// ListRuns returns journal records matching the filter, newest first.
ListRuns(ctx context.Context, filter RunFilter) ([]Run, error)
}
ScheduleManager is the management surface of the durable schedule store: create, reshape, and control schedules, and read the run journal. It is available in DI whenever the cron module is loaded; with the store disabled (vef.cron.store.enabled=false) every method returns ErrStoreDisabled.
type ScheduleSpec ¶ added in v0.40.0
type ScheduleSpec struct {
// Name uniquely identifies the schedule; on a seeded default schedule it
// falls back to the job name.
Name string `json:"name"`
// JobName references the registered JobHandler to execute.
JobName string `json:"jobName"`
// Trigger declares when the schedule fires.
Trigger TriggerSpec `json:"trigger"`
// Params is JSON-marshaled and delivered to the handler on every run;
// json.RawMessage passes through verbatim.
Params any `json:"params,omitempty"`
// StartsAt and EndsAt bound the fire window; either may be nil.
StartsAt *time.Time `json:"startsAt,omitempty"`
EndsAt *time.Time `json:"endsAt,omitempty"`
MisfirePolicy MisfirePolicy `json:"misfirePolicy,omitempty"`
ConcurrencyPolicy ConcurrencyPolicy `json:"concurrencyPolicy,omitempty"`
// Recover re-fires abandoned runs; see Schedule.Recover.
Recover bool `json:"recover,omitempty"`
// Timeout bounds one run and must be an exact whole-millisecond duration;
// zero inherits vef.cron.store.run_timeout.
Timeout time.Duration `json:"timeout,omitempty"`
// Enabled sets the initial (or updated) enablement; nil means true.
Enabled *bool `json:"enabled,omitempty"`
}
ScheduleSpec declares a schedule to create, or the desired state of an update. Zero-valued policies resolve to their defaults (MisfireFireNow, ConcurrencyForbid); a nil Enabled resolves to true.
This is the Go-facing contract and carries idiomatic time.Time and time.Duration values; it is not the wire shape. The management API speaks Unix milliseconds through its own parameters (startsAtUnixMs, timeoutMs and friends), so the tags below describe this struct alone — marshaling it yields different field names than the API, and Timeout marshals as nanoseconds rather than the milliseconds the wire carries.
type Scheduler ¶
type Scheduler interface {
// Jobs returns all jobs currently registered with the scheduler.
Jobs() []Job
// NewJob creates and registers a new job with the scheduler.
// The job will be scheduled according to its definition when the scheduler is running.
// If the task function accepts a context.Context as its first parameter,
// the scheduler will provide cancellation support for graceful shutdown.
NewJob(definition JobDefinition) (Job, error)
// RemoveByTags removes all jobs that have any of the specified tags.
RemoveByTags(tags ...string)
// RemoveJob removes the job with the specified unique identifier.
RemoveJob(id string) error
// Start begins scheduling and executing jobs according to their definitions.
// Jobs added to a running scheduler are scheduled immediately. This method is non-blocking.
Start()
// StopJobs stops the execution of all jobs without removing them from the scheduler.
// Jobs can be restarted by calling Start() again.
StopJobs() error
// Update replaces an existing job's definition while preserving its unique identifier.
// This allows for dynamic job reconfiguration without losing job history.
Update(id string, definition JobDefinition) (Job, error)
// JobsWaitingInQueue returns the number of jobs waiting in the execution queue.
// This is only relevant when using LimitModeWait; otherwise it returns zero.
JobsWaitingInQueue() int
}
Scheduler manages the lifecycle and execution of cron jobs. It provides a high-level interface for job scheduling, management, and control.
func NewScheduler ¶
NewScheduler creates a new Scheduler implementation wrapping the provided gocron.Scheduler. This is the main entry point for creating scheduler instances in the application.
type TriggerKind ¶ added in v0.40.0
type TriggerKind string
TriggerKind identifies how a schedule derives its fire times.
const ( // TriggerCron derives fire times from a cron expression evaluated in an // IANA timezone. TriggerCron TriggerKind = "cron" // TriggerInterval fires at a fixed rate anchored to the schedule's start, // so the fire phase stays stable regardless of catch-ups or manual fires. TriggerInterval TriggerKind = "interval" // TriggerOnce fires a single time. TriggerOnce TriggerKind = "once" )
type TriggerSpec ¶ added in v0.40.0
type TriggerSpec struct {
// Kind selects the trigger semantics.
Kind TriggerKind `json:"kind"`
// Expr is the cron expression of a TriggerCron trigger; 5 or 6 fields
// (leading seconds optional) and @-descriptors are accepted.
Expr string `json:"expr,omitempty"`
// Timezone is the IANA zone a TriggerCron expression is evaluated in;
// empty resolves to DefaultTimezone.
Timezone string `json:"timezone,omitempty"`
// EveryMs is the fixed rate of a TriggerInterval trigger, in milliseconds.
EveryMs int64 `json:"everyMs,omitempty"`
// At is the single fire time of a TriggerOnce trigger.
At *time.Time `json:"at,omitempty"`
}
TriggerSpec is the declarative trigger of a schedule: exactly one kind with its kind-specific fields. Build specs with Expr, Every, or Once.
func Every ¶ added in v0.40.0
func Every(every time.Duration) TriggerSpec
Every returns a fixed-rate trigger. The rate is anchored to the schedule's start (StartsAt, else its creation time), keeping the fire phase stable. Schedules persist the rate in whole milliseconds, so a finer-grained duration truncates toward zero here; rates below MinInterval are refused by Validate either way.
func Expr ¶ added in v0.40.0
func Expr(expr, timezone string) TriggerSpec
Expr returns a cron-expression trigger evaluated in the given IANA timezone; an empty timezone resolves to DefaultTimezone.
func Once ¶ added in v0.40.0
func Once(at time.Time) TriggerSpec
Once returns a single-fire trigger.
func (TriggerSpec) Next ¶ added in v0.40.0
Next returns the first fire time strictly after the given instant, or ok=false when the trigger yields no further occurrence. The anchor fixes the fixed-rate phase of interval triggers and is ignored by other kinds. The spec must have passed Validate; an invalid spec yields no occurrence.
func (TriggerSpec) Occurrences ¶ added in v0.40.0
func (t TriggerSpec) Occurrences(from, to, anchor time.Time, limit int) int
Occurrences counts the fire times in the half-open interval (from, to], capped at limit so pathological gaps (a per-second expression after days of downtime) stay cheap to account for.
func (TriggerSpec) Validate ¶ added in v0.40.0
func (t TriggerSpec) Validate() error
Validate checks the spec for structural soundness: a known kind, a parsable expression and loadable timezone for cron triggers, a rate of at least MinInterval for interval triggers, and a fire time for one-shot triggers.