A Golang job scheduling library that lets you run Go functions at pre-determined intervals using cron expressions, fixed durations, daily, weekly, monthly, or one-time schedules with support for distributed deployments.
Jobs that run once (or at specific future times) then are automatically removed.
func OneTimeJob(startAt OneTimeJobStartAtOption) JobDefinitionRuns once (or at specific future times) then is automatically removed from the scheduler.
Parameters:
startAt: When to run (created with start option functions)Errors:
ErrOneTimeJobStartDateTimePast: All start times are in the pastfunc OneTimeJobStartImmediately() OneTimeJobStartAtOption
func OneTimeJobStartDateTime(start time.Time) OneTimeJobStartAtOption
func OneTimeJobStartDateTimes(times ...time.Time) OneTimeJobStartAtOptionRuns as soon as the executor picks it up (may have queue delay).
gocron.OneTimeJob(gocron.OneTimeJobStartImmediately())Runs at a specific future time.
futureTime := time.Now().Add(1 * time.Hour)
gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(futureTime))Runs at multiple specific times. Job is removed after all times have passed.
gocron.OneTimeJob(gocron.OneTimeJobStartDateTimes(
time.Now().Add(1*time.Hour),
time.Now().Add(2*time.Hour),
time.Now().Add(3*time.Hour),
))j, err := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartImmediately()),
gocron.NewTask(func() {
initializeSystem()
}),
gocron.WithName("init"),
)// Run in 1 hour
futureTime := time.Now().Add(1 * time.Hour)
j, err := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(futureTime)),
gocron.NewTask(func() {
sendScheduledEmail()
}),
)// Run at 3 specific times
j, err := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTimes(
time.Now().Add(1*time.Hour),
time.Now().Add(2*time.Hour),
time.Now().Add(3*time.Hour),
)),
gocron.NewTask(func() {
sendReminder()
}),
gocron.WithName("reminders"),
)// Execute after 30 seconds
delay := time.Now().Add(30 * time.Second)
j, err := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(delay)),
gocron.NewTask(func() {
processDelayedTask()
}),
)Jobs are automatically removed after running:
StartImmediately: Removed immediately after first executionStartDateTime: Removed after the single executionStartDateTimes: Removed after all times have passed"Immediately" means as soon as executor picks it up. There may be a delay if:
LimitModeWait)For StartDateTimes, past times are ignored. At least one time must be in the future, or ErrOneTimeJobStartDateTimePast is returned.
// ERROR: all times in past
_, err := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTimes(
time.Now().Add(-1*time.Hour),
time.Now().Add(-2*time.Hour),
)),
gocron.NewTask(myFunc),
)
// err == ErrOneTimeJobStartDateTimePastj, _ := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartImmediately()),
gocron.NewTask(func() {
loadConfiguration()
warmupCache()
log.Println("System initialized")
}),
gocron.WithName("startup"),
)// Send reminder 1 hour before meeting
meetingTime := time.Date(2024, 3, 15, 14, 0, 0, 0, time.Local)
reminderTime := meetingTime.Add(-1 * time.Hour)
j, _ := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(reminderTime)),
gocron.NewTask(func() {
sendMeetingReminder()
}),
)deadline := time.Date(2024, 3, 20, 17, 0, 0, 0, time.Local)
j, _ := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTimes(
deadline.Add(-7*24*time.Hour), // 1 week before
deadline.Add(-24*time.Hour), // 1 day before
deadline.Add(-1*time.Hour), // 1 hour before
)),
gocron.NewTask(func() {
sendDeadlineReminder()
}),
)func scheduleRetry(s gocron.Scheduler, task func() error, delay time.Duration) {
s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(
time.Now().Add(delay),
)),
gocron.NewTask(func() error {
err := task()
if err != nil {
// Retry again with exponential backoff
scheduleRetry(s, task, delay*2)
}
return err
}),
)
}Not typically needed since OneTimeJob auto-removes, but you can combine:
j, _ := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartImmediately()),
gocron.NewTask(myFunc),
gocron.WithLimitedRuns(1), // Redundant but harmless
)j, _ := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartImmediately()),
gocron.NewTask(func() {
initializeSystem()
}),
gocron.WithEventListeners(
gocron.AfterJobRuns(func(jobID uuid.UUID, jobName string) {
log.Printf("Initialization complete: %s", jobName)
}),
),
)ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
j, _ := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartImmediately()),
gocron.NewTask(func(ctx context.Context) error {
return longRunningInitialization(ctx)
}),
gocron.WithContext(ctx),
)pastTime := time.Now().Add(-1 * time.Hour)
_, err := s.NewJob(
gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(pastTime)),
gocron.NewTask(myFunc),
)
if errors.Is(err, gocron.ErrOneTimeJobStartDateTimePast) {
log.Println("Cannot schedule job in the past")
}Install with Tessl CLI
npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1docs
api
examples
guides