Documentation
¶
Overview ¶
Package scheduler provides a config-driven cron/interval job scheduler as a lakta AsyncModule, wrapping go-co-op/gocron v2 with code-owned handlers, otel spans, panic recovery, overlap policies, per-job timezone/jitter and hot-reload.
Index ¶
- type Config
- type JobInfo
- type JobSpec
- type Module
- func (m *Module) ConfigPath() string
- func (m *Module) Dependencies() ([]reflect.Type, []reflect.Type)
- func (m *Module) Init(ctx context.Context) error
- func (m *Module) LoadConfig(k *koanf.Koanf) error
- func (m *Module) OnReload(k *koanf.Koanf)
- func (m *Module) Provides() []reflect.Type
- func (m *Module) Shutdown(ctx context.Context) error
- func (m *Module) StartAsync(_ context.Context) error
- type Option
- type OverlapPolicy
- type Scheduler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Instance name; DefaultInstanceName by default.
Name string `koanf:"-"`
// Timezone is the scheduler-wide default location (IANA name). Per-job
// JobSpec.Timezone overrides it. Defaults to "UTC".
Timezone string `koanf:"timezone"`
// Jobs holds config-declared job overlays. Prefer snake_case names;
// hyphens cannot be overridden via environment variables.
Jobs map[string]JobSpec `koanf:"jobs"`
// CodeJobs holds jobs registered via WithJob (code-only). A config entry
// with the same name overlays it field-by-field (config wins per field);
// the Handler always persists.
CodeJobs map[string]JobSpec `code_only:"WithJob" koanf:"-"`
}
Config is the worker-scheduler module config. Mirrors pool.Config: a config map (Jobs) overlays a code-only map (CodeJobs) by name via MergedJobs.
func NewDefaultConfig ¶
func NewDefaultConfig() Config
NewDefaultConfig returns default configuration.
func (*Config) LoadFromKoanf ¶
LoadFromKoanf loads configuration from koanf instance at the given path.
func (*Config) MergedJobs ¶
MergedJobs copies CodeJobs then overlays Jobs field-by-field per name; config wins per field while the code-owned Handler always persists (config never carries a func).
type JobInfo ¶
type JobInfo struct {
Name string
Schedule string
Timezone string
Enabled bool
NextRun time.Time
LastRun time.Time
}
JobInfo is the flat, gocron-free introspection record the actuator reads via Scheduler.Jobs. No gocron types leak.
type JobSpec ¶
type JobSpec struct {
Schedule string `koanf:"schedule"` // 6-field cron (seconds) or "@every 5m"
Timezone string `koanf:"timezone"` // per-job override of Config.Timezone; "" inherits
Jitter time.Duration `koanf:"jitter"` // 0 = none
Overlap OverlapPolicy `koanf:"overlap"` // "" defaults to OverlapSkip in translation
// Enabled uses nil = true; false = never registered. This is the OPPOSITE
// convention to the actuator's enabled:false default — here a job is on
// unless a config entry explicitly disables it.
Enabled *bool `koanf:"enabled"`
// Handler runs per fire. koanf:"-" keeps config from ever carrying a func;
// it survives hot-reload because config only overlays the other fields.
Handler func(ctx context.Context) error `koanf:"-"`
}
JobSpec declares one scheduled job. Handler is code-owned (never from YAML); every other field is config-overridable by job name.
type Module ¶
Module wires a Scheduler into DI as an AsyncModule.
func (*Module) ConfigPath ¶
ConfigPath returns the koanf path for this module's configuration.
func (*Module) Dependencies ¶
Dependencies declares the optional types this module needs from DI before Init. The otel module always provides a MeterProvider (noop when disabled), so declaring it orders otel before the scheduler; the tracer is resolved analogously and falls back to noop when otel is absent entirely.
func (*Module) Init ¶
Init builds the gocron scheduler, registers every merged job, and provides the Scheduler to the injector so app modules can Register more jobs during their own Init (topo-sort guarantees scheduler inits first when declared a dep).
func (*Module) LoadConfig ¶
LoadConfig loads configuration from koanf.
func (*Module) OnReload ¶
OnReload re-loads config then diffs MergedJobs against the live specs: added names get Registered, removed names get removed, and any name whose schedule/tz/jitter/overlap/enabled changed is re-Registered. Handlers are code-owned and persist across reload (config never carries a func).
type Option ¶
type Option func(m *Config)
Option configures the Module.
func WithJob ¶
WithJob registers a code-owned job. Seeds CodeJobs[name] with Schedule + Handler; the remaining JobSpec fields keep their zero defaults and config may override them by the same name.
func WithTimezone ¶
WithTimezone sets the scheduler-wide default location (code-only; the config timezone key still wins on load).
type OverlapPolicy ¶
type OverlapPolicy string
OverlapPolicy controls what happens when a job's previous run is still in flight at its next fire. Maps to a gocron singleton mode.
const ( OverlapSkip OverlapPolicy = "skip" // drop the overlapping run (LimitModeReschedule) OverlapQueue OverlapPolicy = "queue" // serialize: run after the current one (LimitModeWait) OverlapAllow OverlapPolicy = "allow" // no singleton option; runs may overlap )
type Scheduler ¶
type Scheduler struct {
// contains filtered or unexported fields
}
Scheduler wraps a gocron.Scheduler plus a name→job map, guarded by mu for concurrent Register/RunNow during hot-reload.
func (*Scheduler) NextRun ¶
NextRun returns the next scheduled fire for name. Unknown name errors as above.