CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/golang-github-com-go-co-op-gocron-v2

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.

Overview
Eval results
Files

advanced-scheduling.mddocs/guides/

Advanced Scheduling

Guide to advanced scheduling patterns and techniques.

Overview

Beyond basic intervals and cron expressions, gocron supports sophisticated scheduling patterns for complex use cases.

Time-Based Scheduling

Schedule jobs at specific times of day, week, or month.

Daily Scheduling

// Run at 9 AM and 5 PM every day
j, _ := s.NewJob(
    gocron.DailyJob(
        1,
        gocron.NewAtTimes(
            gocron.NewAtTime(9, 0, 0),
            gocron.NewAtTime(17, 0, 0),
        ),
    ),
    gocron.NewTask(dailyReport),
)

Weekly Scheduling

// Run every Monday at 9 AM
j, _ := s.NewJob(
    gocron.WeeklyJob(
        1,
        gocron.NewWeekdays(time.Monday),
        gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0)),
    ),
    gocron.NewTask(weeklyReport),
)

Monthly Scheduling

// Run on 1st and 15th of month at midnight
j, _ := s.NewJob(
    gocron.MonthlyJob(
        1,
        gocron.NewDaysOfTheMonth(1, 15),
        gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
    ),
    gocron.NewTask(monthlyReport),
)

Detailed guide: Time-Based Scheduling

Random Intervals

Add jitter to prevent thundering herd:

// Random interval between 1-5 minutes
j, _ := s.NewJob(
    gocron.DurationRandomJob(
        time.Minute,
        5*time.Minute,
    ),
    gocron.NewTask(healthCheck),
)

Start and Stop Times

Limit job execution window:

// Run only during business hours
j, _ := s.NewJob(
    gocron.DurationJob(time.Minute),
    gocron.NewTask(businessTask),
    gocron.WithStartAt(
        gocron.WithStartDateTime(
            time.Date(2024, 1, 1, 9, 0, 0, 0, time.Local),
        ),
    ),
    gocron.WithLimitRunsTo(480), // 8 hours * 60 minutes
)

Timezone-Aware Scheduling

Scheduler Timezone

loc, _ := time.LoadLocation("America/Chicago")
s, _ := gocron.NewScheduler(
    gocron.WithLocation(loc),
)

Per-Job Timezone (Cron Only)

j, _ := s.NewJob(
    gocron.CronJob("TZ=America/New_York 0 9 * * *", false),
    gocron.NewTask(doWork),
)

Conditional Execution

Skip execution based on runtime conditions:

j, _ := s.NewJob(
    gocron.DurationJob(time.Minute),
    gocron.NewTask(func() {
        if shouldSkip() {
            return
        }
        doWork()
    }),
)

Run Immediately on Start

Execute job once immediately, then on schedule:

j, _ := s.NewJob(
    gocron.DurationJob(time.Hour),
    gocron.NewTask(initialize),
    gocron.WithStartAt(
        gocron.WithStartImmediately(),
    ),
)

Interval from Completion

Ensure fixed rest period between executions:

j, _ := s.NewJob(
    gocron.DurationJob(5*time.Minute),
    gocron.NewTask(rateLimitedAPI),
    gocron.WithIntervalFromCompletion(), // 5min rest after completion
)

One-Time Jobs

Execute once at specific time:

j, _ := s.NewJob(
    gocron.OneTimeJob(
        gocron.OneTimeJobStartDateTime(
            time.Now().Add(time.Hour),
        ),
    ),
    gocron.NewTask(initializeSystem),
)

Chaining Jobs

Execute jobs in sequence:

// Job 1
j1, _ := s.NewJob(
    gocron.DurationJob(time.Hour),
    gocron.NewTask(step1),
    gocron.WithEventListeners(
        gocron.AfterJobRuns(func(jobID uuid.UUID, jobName string) {
            // Trigger job 2
            j2.RunNow()
        }),
    ),
)

// Job 2
j2, _ := s.NewJob(
    gocron.DurationJob(24*time.Hour), // Normally runs daily
    gocron.NewTask(step2),
)

Dynamic Job Updates

Update jobs at runtime:

// Create initial job
j, _ := s.NewJob(
    gocron.DurationJob(time.Minute),
    gocron.NewTask(myFunc),
)

// Later, update interval
newJob, err := s.Update(
    j.ID(),
    gocron.DurationJob(5*time.Minute), // New interval
    gocron.NewTask(myFunc),
)

Job Pools

Create multiple instances of same job:

for i := 0; i < 5; i++ {
    workerID := i
    s.NewJob(
        gocron.DurationJob(time.Minute),
        gocron.NewTask(func() {
            processQueue(workerID)
        }),
        gocron.WithName(fmt.Sprintf("worker-%d", workerID)),
        gocron.WithTags("worker", "queue"),
    )
}

Custom Scheduling Logic

Implement complex scheduling with cron:

// Run every weekday at 9 AM
j, _ := s.NewJob(
    gocron.CronJob("0 9 * * 1-5", false),
    gocron.NewTask(weekdayTask),
)

// Run last day of month
j, _ = s.NewJob(
    gocron.CronJob("0 0 L * *", false), // Last day
    gocron.NewTask(monthEndTask),
)

Performance Considerations

Job Limits

// Limit total runs
j, _ := s.NewJob(
    gocron.DurationJob(time.Minute),
    gocron.NewTask(myFunc),
    gocron.WithLimitRunsTo(100),
)

Concurrency Control

// Prevent overlapping runs
j, _ := s.NewJob(
    gocron.DurationJob(30*time.Second),
    gocron.NewTask(slowOperation),
    gocron.WithSingletonMode(gocron.LimitModeReschedule),
)

Production Patterns

Best practices for production deployments.

Detailed guide: Production Patterns

See Also

Install with Tessl CLI

npx tessl i tessl/golang-github-com-go-co-op-gocron-v2

docs

index.md

tile.json