The core scheduler manages the lifecycle of cron jobs, including starting, stopping, and running jobs on their configured schedules.
// New creates a new Cron job runner with optional configuration.
// Returns a scheduler with default settings if no options are provided.
//
// Available Settings:
// - Time Zone: Defaults to time.Local
// - Parser: Defaults to standard 5-field cron spec
// - Chain: Defaults to a chain that recovers panics
// - Logger: Defaults to DefaultLogger
func New(opts ...Option) *CronType Definitions:
type Cron struct {
// contains unexported fields
}
type Option func(*Cron)import (
"time"
"github.com/robfig/cron/v3"
)
// Basic scheduler with defaults
c := cron.New()
// Scheduler with custom timezone
nyc, _ := time.LoadLocation("America/New_York")
c := cron.New(cron.WithLocation(nyc))
// Scheduler with seconds field in cron specs
c := cron.New(cron.WithSeconds())
// Scheduler with multiple options
c := cron.New(
cron.WithLocation(nyc),
cron.WithSeconds(),
cron.WithLogger(cron.VerbosePrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags))),
)// Start begins the scheduler in its own goroutine.
// This is a no-op if the scheduler is already running.
func (c *Cron) Start()Usage:
c := cron.New()
// Add jobs before starting
c.AddFunc("@hourly", func() { fmt.Println("Job 1") })
// Start in background
c.Start()
// Can continue adding jobs while running
c.AddFunc("@daily", func() { fmt.Println("Job 2") })
// Main program continues...// Run starts the scheduler synchronously (blocking).
// This is a no-op if the scheduler is already running.
// The calling goroutine will be blocked until Stop() is called.
func (c *Cron) Run()Usage:
c := cron.New()
c.AddFunc("@every 5s", func() { fmt.Println("Running") })
// This blocks until Stop() is called
c.Run()// Stop stops the scheduler if running; otherwise does nothing.
// A context is returned so the caller can wait for running jobs to complete.
// The scheduler can be restarted after stopping.
func (c *Cron) Stop() context.ContextUsage:
c := cron.New()
c.AddFunc("@every 1s", func() {
fmt.Println("Working...")
time.Sleep(10 * time.Second) // Long-running job
})
c.Start()
// Later: stop the scheduler
ctx := c.Stop()
// Wait for all jobs to complete
<-ctx.Done()
fmt.Println("All jobs finished")package main
import (
"context"
"fmt"
"time"
"github.com/robfig/cron/v3"
)
func main() {
// Create scheduler with verbose logging
c := cron.New(
cron.WithLogger(cron.VerbosePrintfLogger(
log.New(os.Stdout, "cron: ", log.LstdFlags),
)),
)
// Add jobs
c.AddFunc("*/5 * * * *", func() {
fmt.Println("Every 5 minutes")
})
c.AddFunc("0 0 * * *", func() {
fmt.Println("Daily at midnight")
})
// Start scheduler
c.Start()
fmt.Println("Scheduler started")
// Run for a while
time.Sleep(1 * time.Hour)
// Stop and wait for jobs to finish
fmt.Println("Stopping scheduler...")
ctx := c.Stop()
// Wait up to 30 seconds for jobs to complete
waitCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
select {
case <-ctx.Done():
fmt.Println("All jobs completed")
case <-waitCtx.Done():
fmt.Println("Timeout waiting for jobs to complete")
}
}All Cron methods (Start, Stop, AddFunc, AddJob, Schedule, Remove, Entries, Entry) are designed to be thread-safe. The caller must ensure invocations have a clear happens-before ordering between them, but concurrent access from multiple goroutines is safe.
New(), the scheduler is in a stopped stateStart() or Run() is calledStop() prevents new job executionsStart() or Run()The scheduler:
If no entries are scheduled, the scheduler sleeps indefinitely until a new entry is added or it's stopped.