quartz for Go

github.com/malcolmston/quartz

A Quartz-style job scheduler for Go, stdlib only.

 GitHubports quartz-scheduler/quartz

A from-scratch, standard-library-only Go take on the classic Quartz job scheduler — no cgo, no third-party dependencies. You get Jobs (any Execute(context.Context) error, plus a JobFunc adapter and a JobDataMap for per-job state), two Trigger implementations, and a Scheduler that fires due triggers on a bounded worker pool. SimpleTrigger covers start-time-plus-interval-plus-repeat schedules; CronTrigger runs on a real cron parser supporting five- or six-field expressions with ranges, steps, lists, names and the * / ? wildcards, evaluated in any *time.Location. The scheduler adds graceful shutdown with drain, per-trigger and per-job pause/resume, configurable misfire policies, and job/trigger listeners that can veto a fire. Storage sits behind a JobStore interface with an in-memory implementation, and every fire-time decision flows through an injectable clock so schedules are fully deterministic and testable without sleeping.

Install

shell
$ go get github.com/malcolmston/quartz

Quick start

main.go
import "github.com/malcolmston/quartz"

// A pool of 4 workers running in real time.
s := quartz.NewScheduler(quartz.Options{Concurrency: 4})

job := quartz.NewJobDetail(quartz.NewKey("daily-report"),
    quartz.JobFunc(func(ctx context.Context) error {
        fmt.Println("generating report")
        return nil
    }))

// Fire every day at 10:00:00.
trigger, _ := quartz.NewCronTriggerWithKeys(
    quartz.NewKey("report-trigger"), job.Key(), "0 0 10 * * *")

s.ScheduleJob(job, trigger)
s.Start()
defer s.Shutdown(true) // graceful drain

Features

  • Jobs — any Job (Execute(context.Context) error), a JobFunc adapter, and a JobDataMap of per-job state carried through each fire
  • JobDetail — names a job via a Key, with WithDescription, WithData and Durable builder options
  • SimpleTrigger — start time plus a fixed Interval and a repeat count (or RepeatForever), with an optional end time
  • CronTrigger over a real parser — ParseCron/CronExpression handle 5/6 fields, ranges (1-5), steps (*/15), lists, names and ?, evaluated in any *time.Location via In
  • SchedulerNewScheduler with a bounded Options.Concurrency worker pool, ScheduleJob, Start, and Shutdown with optional drain
  • Pause / resume — PauseTrigger/ResumeTrigger and PauseJob/ResumeJob, plus out-of-band TriggerJob
  • Misfire policies — MisfireSmart, MisfireFireNow, MisfireIgnore and MisfireDoNothing via WithMisfirePolicy
  • Listeners — JobListener and TriggerListener hooks (embed BaseJobListener/BaseTriggerListener); a trigger listener can VetoJobExecution
  • Pluggable storage — a JobStore interface with an in-memory MemoryJobStore (NewMemoryJobStore)
  • Injectable clock — Options.Clock plus ProcessDue drive cron and next-fire logic deterministically in tests, without sleeping
  • Zero dependencies — pure Go standard library, nothing to audit but the toolchain
quartz