### Basic gocron Setup Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Illustrates the fundamental steps for setting up and running a basic job with gocron. This is useful for new users to quickly get a job scheduled. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Define a job _, err = scheduler.NewTask(func() { fmt.Println("I will print a message every second") }) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Basic gocron Setup Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Demonstrates the basic setup of a gocron scheduler, including creating a scheduler, adding a job that runs every 10 seconds, starting the scheduler, and shutting it down. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create scheduler scheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Add a job job, err := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() { fmt.Println("Task executed") }), ) if err != nil { panic(err) } fmt.Printf("Job created: %s\n", job.ID()) // Start scheduler scheduler.Start() // Let it run for a bit time.Sleep(30*time.Second) // Shutdown err = scheduler.Shutdown() if err != nil { panic(err) } } ``` -------------------------------- ### Install gocron mocks Source: https://github.com/go-co-op/gocron/blob/v2/mocks/README.md Use 'go get' to install the gocron mocks package for version 2. ```bash go get github.com/go-co-op/gocron/mocks/v2 ``` -------------------------------- ### Quick Start: Create and Run a Job with gocron Source: https://github.com/go-co-op/gocron/blob/v2/README.md This example demonstrates how to create a new scheduler, add a job that runs every 10 seconds, start the scheduler, and gracefully shut it down. Ensure proper error handling for scheduler and job creation. ```golang package main import ( "fmt" time "time" "github.com/go-co-op/gocron/v2" ) func main() { // create a scheduler ss, err := gocron.NewScheduler() if err != nil { // handle error } // add a job to the scheduler j, err := s.NewJob( gocron.DurationJob( 10*time.Second, ), gocron.NewTask( func(a string, b int) { // do things }, "hello", 1, ), ) if err != nil { // handle error } // each job has a unique id fmt.Println(j.ID()) // start the scheduler s.Start() // block until you are ready to shut down select { case <-time.After(time.Minute): } // when you're done, shut it down err = s.Shutdown() // or for context-aware teardown: // err = s.ShutdownWithContext(ctx) if err != nil { // handle error } } ``` -------------------------------- ### Install gocron Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Install the gocron library using go get. ```bash go get github.com/go-co-op/gocron/v2 ``` -------------------------------- ### Start and Stop Scheduler: v1 vs v2 Source: https://github.com/go-co-op/gocron/blob/v2/migration_v1_to_v2.md v2 uses Start() to begin scheduling and Shutdown() for graceful cleanup, replacing v1's StartAsync() and Stop(). ```go s.StartAsync() s.Stop() ``` ```go s.Start() s.Shutdown() ``` -------------------------------- ### Start Scheduler Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Begin the execution of scheduled jobs. ```go scheduler.Start() ``` -------------------------------- ### Create Job with Start and Stop Times Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Configure a job with both a specific start and end datetime. Ensure the stop time is not earlier than the start time to avoid errors. ```go start := time.Now() end := start.Add(24*time.Hour) job, _ := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() { fmt.Println("task") }), gocron.WithStartAt(gocron.WithStartDateTime(start)), gocron.WithStopAt(gocron.WithStopDateTime(end)), ) ``` -------------------------------- ### Job Options: Start Immediately Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Configures a job to start executing immediately upon scheduler startup. This is useful for tasks that should begin without delay. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job to run immediately and then every 10 seconds _, err = scheduler.NewTask( gocron.NewDurationJob(10*time.Second, func() { fmt.Println("I will run immediately and then every 10 seconds") }), gocron.WithStartImmediately(), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Example Monitor Implementation (Prometheus) Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/monitors-and-logging.md An example implementation of the Monitor interface using Prometheus metrics. ```APIDOC ## Prometheus Monitor Example This example demonstrates how to implement the `Monitor` interface using Prometheus metrics. ### PrometheusMonitor Struct ```go type PrometheusMonitor struct { jobsCompleted prometheus.Counter jobsFailed prometheus.Counter executionTime prometheus.Histogram } ``` ### IncrementJob Implementation ```go func (m *PrometheusMonitor) IncrementJob( id uuid.UUID, name string, tags []string, status JobStatus, ) { switch status { case gocron.Success: m.jobsCompleted.Inc() case gocron.Fail: m.jobsFailed.Inc() } } ``` ### RecordJobTiming Implementation ```go func (m *PrometheusMonitor) RecordJobTiming( startTime, endTime time.Time, id uuid.UUID, name string, tags []string, ) { duration := endTime.Sub(startTime) m.executionTime.Observe(duration.Seconds()) } ``` ### Scheduler Initialization with Custom Monitor ```go // Assuming myMonitor is an initialized instance of a type that implements the Monitor interface // For example: // myMonitor := &PrometheusMonitor{...} scheduler, _ := gocron.NewScheduler( gocron.WithMonitor(myMonitor), ) ``` ``` -------------------------------- ### Custom Cron Implementation Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/types.md Provides an example of a custom cron implementation that satisfies the `Cron` interface. It parses a crontab and calculates the next run time. ```go type CustomCron struct { schedule cron.Schedule } func (c *CustomCron) IsValid(crontab string, location *time.Location, now time.Time) error { schedule, err := cron.ParseStandard(crontab) if err != nil { return err } c.schedule = schedule return nil } func (c *CustomCron) Next(lastRun time.Time) time.Time { return c.schedule.Next(lastRun) } ``` -------------------------------- ### Job Options: Start at Specific Time Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Configures a job to start at a predefined time. This allows for controlled initiation of scheduled tasks. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job to start at a specific time and then run every hour startTime := time.Now().Add(5 * time.Minute) _, err = scheduler.NewTask( gocron.NewDurationJob(time.Hour, func() { fmt.Println("I will run every hour, starting in 5 minutes") }), gocron.WithStartAt(startTime), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Event Listener: Before Job Runs Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Attaches a function to be executed just before a job starts. This can be used for setup or logging purposes. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job with a 'BeforeJobRuns' event listener _, err = scheduler.NewTask( gocron.NewDurationJob(time.Minute, func() { fmt.Println("Job is running...") }), gocron.BeforeJobRuns(func() { fmt.Println("Event: Job is about to run!") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Start Scheduler Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Begins scheduling jobs for execution. This operation is non-blocking. Jobs added after starting are scheduled immediately. ```go scheduler.Start() defer scheduler.Shutdown() // Jobs now execute on schedule select { case <-time.After(5*time.Minute): } ``` -------------------------------- ### Create Job with Specific Start Time Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Configure a job to start at a precise future datetime using WithStartAt and WithStartDateTime. Ensure the specified time is not in the past to avoid errors. ```go future := time.Now().Add(5*time.Minute) job, _ := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() { fmt.Println("task") }), gocron.WithStartAt(gocron.WithStartDateTime(future)), ) ``` -------------------------------- ### Create Job with Immediate Start Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Use WithStartAt with WithStartImmediately to configure a job to run as soon as possible, then continue with its regular schedule. ```go job, _ := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() { fmt.Println("task") }), gocron.WithStartAt(gocron.WithStartImmediately()), ) ``` -------------------------------- ### Default Cron Usage Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/types.md Demonstrates how to create and use the default cron implementation. It validates a crontab string. ```go cron := gocron.NewDefaultCron(false) err := cron.IsValid("0 9 * * *", time.Local, time.Now()) if err != nil { log.Fatal("Invalid crontab:", err) } ``` -------------------------------- ### Configure Job Start and Stop Times Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Schedule jobs to start at a specific future time or to stop running after a certain duration. Jobs can also be configured to start immediately. ```go // Start in 10 minutes future := time.Now().Add(10*time.Minute) scheduler.NewJob( gocron.DurationJob(1*time.Hour), gocron.NewTask(func() { doWork() }), gocron.WithStartAt(gocron.WithStartDateTime(future)), ) // Run for only 24 hours end := time.Now().Add(24*time.Hour) scheduler.NewJob( gocron.DurationJob(1*time.Hour), gocron.NewTask(func() { doWork() }), gocron.WithStopAt(gocron.WithStopDateTime(end)), ) // Start immediately and run for 24 hours end := time.Now().Add(24*time.Hour) scheduler.NewJob( gocron.DurationJob(1*time.Hour), gocron.NewTask(func() { doWork() }), gocron.WithStartAt(gocron.WithStartImmediately()), gocron.WithStopAt(gocron.WithStopDateTime(end)), ) ``` -------------------------------- ### Custom Elector Implementation Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/distributed-scheduling.md Provides an example of a custom Elector implementation. Use this to integrate your own consensus or election mechanism. ```go type MyElector struct { // Implementation-specific fields } func (e *MyElector) IsLeader(ctx context.Context) error { // Check election/consensus mechanism if isLeader := e.checkConsensus(ctx); !isLeader { return fmt.Errorf("not the leader") } return nil } scheduler, _ := gocron.NewScheduler( gocron.WithDistributedElector(myElector), ) ``` -------------------------------- ### Custom Lock Implementation Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/distributed-scheduling.md An example implementation of the Lock interface using a Redis client to release a lock. ```go type MyLock struct { client *redis.Client key string } func (l *MyLock) Unlock(ctx context.Context) error { return l.client.Del(ctx, l.key).Err() } ``` -------------------------------- ### Custom Logger Implementation Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/monitors-and-logging.md Example of how to implement the Logger interface for custom logging. This logger can then be provided to the scheduler using WithLogger. ```go type MyLogger struct{} func (l MyLogger) Debug(msg string, args ...any) { // Implementation } func (l MyLogger) Error(msg string, args ...any) { // Implementation } func (l MyLogger) Info(msg string, args ...any) { // Implementation } func (l MyLogger) Warn(msg string, args ...any) { // Implementation } scheduler, _ := gocron.NewScheduler( gocron.WithLogger(MyLogger{}), ) ``` -------------------------------- ### AtTime to time.Time Conversion Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/types.md Shows how to use the `TimeFromAtTime` helper function to convert an `AtTime` to a `time.Time` and print its hour and minute. ```go atTime := gocron.NewAtTime(9, 30, 0) t := gocron.TimeFromAtTime(atTime, time.UTC) fmt.Printf("Hour: %d, Minute: %d\n", t.Hour(), t.Minute()) ``` -------------------------------- ### Start Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Begins scheduling jobs for execution based on their definitions. This operation is non-blocking, and jobs added after Start is called are scheduled immediately. ```APIDOC ## Start() ### Description Begins scheduling jobs for execution based on their definitions. This is non-blocking. Jobs added after Start is called are scheduled immediately based on their definition. ### Request Example ```go scheduler.Start() defer scheduler.Shutdown() // Jobs now execute on schedule select { case <-time.After(5*time.Minute): } ``` ``` -------------------------------- ### Cron Job Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Demonstrates how to schedule a job using cron syntax. This is suitable for recurring tasks that need precise timing. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler( gocron.WithDistributedLocker(gocron.NewRedisLocker(&redis.Client{}), // Optional: specify a prefix for the keys in Redis // gocron.WithRedisLockerKeyPrefix("gocron-") ), ) if err != nil { panic(err) } // Schedule a job to run every minute _, err = scheduler.NewTask( gocron.NewCronJob("*/1 * * * *", func() { fmt.Println("I will run every minute") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Create New Scheduler Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Instantiate a new Scheduler. The scheduler is not active until Start() is called. Options can be provided for configuration. ```go s, err := gocron.NewScheduler() if err != nil { log.Fatal(err) } ``` ```go s, err := gocron.NewScheduler( gocron.WithLocation(time.UTC), gocron.WithLogger(gocron.NewLogger(gocron.LogLevelInfo)), ) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Daily Job Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Demonstrates scheduling a job to run once a day at a specific time. This is ideal for tasks that need to be performed daily. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job to run every day at 10:30 AM _, err = scheduler.NewTask( gocron.NewDailyJob(gocron.NewAtTime(10, 30, 0), func() { fmt.Println("I will run every day at 10:30 AM") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### NewLogger Function Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Shows how to create a custom logger instance using the NewLogger function. This allows for integration with existing logging frameworks or custom logging logic. ```go package main import ( "fmt" "log" "os" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a custom logger that writes to standard output logger := gocron.NewLogger(log.New(os.Stdout, "gocron: ", log.LstdFlags|log.Lmicroseconds)) // Create a new scheduler with the custom logger sscheduler, err := gocron.NewScheduler( gocron.WithLogger(logger), ) if err != nil { panic(err) } // Schedule a job _, err = scheduler.NewTask( gocron.NewDurationJob(time.Second, func() { fmt.Println("Job is running with custom logger") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Create Job with Past Start Time Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Set a job's start time to a past date for backfilling purposes using WithStartAt and WithStartDateTimePast. Avoid using a zero time value to prevent errors. ```go // Start from a week ago pastTime := time.Now().Add(-7*24*time.Hour) job, _ := scheduler.NewJob( gocron.DurationJob(1*time.Hour), gocron.NewTask(func() { fmt.Println("task") }), gocron.WithStartAt(gocron.WithStartDateTimePast(pastTime)), ) ``` -------------------------------- ### NewScheduler Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Creates a new Scheduler instance. The scheduler is not started until Start() is called. It can be configured with various options. ```APIDOC ## NewScheduler() ### Description Creates a new Scheduler instance. The scheduler is not started until `Start()` is called. ### Signature ```go func NewScheduler(options ...SchedulerOption) (Scheduler, error) ``` ### Parameters #### Variadic Options (`options`) - `...SchedulerOption` - Optional - Variadic options to configure the scheduler. ### Returns - `Scheduler` - The newly created scheduler instance. - `error` - Error if initialization fails. ### Errors - `ErrWithClockNil` - If WithClock option receives nil clock. - `ErrWithDistributedElectorNil` - If WithDistributedElector option receives nil elector. - `ErrWithDistributedLockerNil` - If WithDistributedLocker option receives nil locker. - `ErrWithLimitConcurrentJobsZero` - If WithLimitConcurrentJobs limit is zero. - `ErrWithLocationNil` - If WithLocation option receives nil location. - `ErrWithLoggerNil` - If WithLogger option receives nil logger. - `ErrWithMonitorNil` - If WithMonitor option receives nil monitor. - `ErrWithStopTimeoutZeroOrNegative` - If WithStopTimeout is non-positive. - `ErrSchedulerMonitorNil` - If WithSchedulerMonitor option receives nil monitor. ### Example ```go s, err := gocron.NewScheduler() if err != nil { log.Fatal(err) } // with options s, err := gocron.NewScheduler( gocron.WithLocation(time.UTC), gocron.WithLogger(gocron.NewLogger(gocron.LogLevelInfo)), ) if err != nil { log.Fatal(err) } ``` ``` -------------------------------- ### Common Patterns Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/helper-functions.md Examples demonstrating common job scheduling patterns. ```APIDOC ## Common Patterns ### Business Hours Daily ```go job, _ := scheduler.NewJob( gocron.DailyJob(1, gocron.NewAtTimes( gocron.NewAtTime(9, 0, 0), gocron.NewAtTime(12, 0, 0), gocron.NewAtTime(17, 0, 0), )), gocron.NewTask(func() { fmt.Println("Business hours check") }), ) ``` ### Weekday Morning Standup ```go job, _ := scheduler.NewJob( gocron.WeeklyJob(1, gocron.NewWeekdays( time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday, ), gocron.NewAtTimes(gocron.NewAtTime(10, 0, 0)), ), gocron.NewTask(func() { fmt.Println("Daily standup") }), ) ``` ### Monthly Report ```go job, _ := scheduler.NewJob( gocron.MonthlyJob(1, gocron.NewDaysOfTheMonth(1), // First day of month gocron.NewAtTimes(gocron.NewAtTime(8, 0, 0)), ), gocron.NewTask(func() { fmt.Println("Monthly report") }), ) ``` ### End-of-Month Cleanup ```go job, _ := scheduler.NewJob( gocron.MonthlyJob(1, gocron.NewDaysOfTheMonth(-1), // Last day of month gocron.NewAtTimes(gocron.NewAtTime(23, 59, 0)), ), gocron.NewTask(func() { fmt.Println("End-of-month cleanup") }), ) ``` ### Quarterly Report (Every 3 Months on 1st) ```go job, _ := scheduler.NewJob( gocron.MonthlyJob(3, // Every 3 months gocron.NewDaysOfTheMonth(1), gocron.NewAtTimes(gocron.NewAtTime(6, 0, 0)), ), gocron.NewTask(func() { fmt.Println("Quarterly report") }), ) ``` ### Multiple Schedules on Same Day ```go job, _ := scheduler.NewJob( gocron.WeeklyJob(1, gocron.NewWeekdays(time.Friday), gocron.NewAtTimes( gocron.NewAtTime(15, 0, 0), // 3:00 PM - Team meeting gocron.NewAtTime(16, 30, 0), // 4:30 PM - Send report ), ), gocron.NewTask(func() { fmt.Println("Friday tasks") }), ) ``` ``` -------------------------------- ### Write a test with gocron mocks Source: https://github.com/go-co-op/gocron/blob/v2/mocks/README.md Example of how to write a test for a function that uses gocron.Scheduler with gomock. ```golang package main import ( t "testing" "github.com/go-co-op/gocron/mocks/v2" "github.com/go-co-op/gocron/v2" "go.uber.org/mock/gomock" ) func myFunc(s gocron.Scheduler) { s.Start() _ = s.Shutdown() } func TestMyFunc(t *testing.T) { ctrl := gomock.NewController(t) s := gocronmocks.NewMockScheduler(ctrl) s.EXPECT().Start().Times(1) s.EXPECT().Shutdown().Times(1).Return(nil) myFunc(s) } ``` -------------------------------- ### Get All Jobs Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Retrieve a list of all jobs currently scheduled. ```go scheduler.Jobs() ``` -------------------------------- ### One-Time Job Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Shows how to schedule a job to run only once at a specific date and time. Useful for one-off tasks or scheduled events. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job to run once on December 25th, 2023 at 10:00 AM targetTime := time.Date(2023, 12, 25, 10, 0, 0, 0, time.UTC) _, err = scheduler.NewTask( gocron.NewOneTimeJob(targetTime, func() { fmt.Println("I will run only once on December 25th, 2023 at 10:00 AM") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Custom Locker Implementation Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/distributed-scheduling.md Demonstrates a custom Locker implementation using Redis. This ensures that a job is executed by only one scheduler instance at a time. ```go type MyLocker struct { client *redis.Client } func (l *MyLocker) Lock(ctx context.Context, key string) (gocron.Lock, error) { // Implementation using Redis or similar lock, err := l.client.SetNX(ctx, key, uuid.New().String(), 30*time.Second).Result() if err != nil || !lock { return nil, fmt.Errorf("could not acquire lock") } return &myLock{client: l.client, key: key}, nil } scheduler, _ := gocron.NewScheduler( gocron.WithDistributedLocker(myLocker), ) ``` -------------------------------- ### Weekly Job Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Shows how to schedule a job to run on specific days of the week at a particular time. Useful for weekly reports or maintenance tasks. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job to run every Monday and Friday at 2:00 PM _, err = scheduler.NewTask( gocron.NewWeeklyJob(gocron.NewWeekdays(time.Monday, time.Friday), gocron.NewAtTime(14, 0, 0), func() { fmt.Println("I will run every Monday and Friday at 2:00 PM") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Configure Job Options Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/README.md Set various options for jobs, such as name, tags, run limits, start times, and event listeners. ```go gocron.WithName("job_name") ``` ```go gocron.WithTags("tag1", "tag2") ``` ```go gocron.WithLimitedRuns(5) ``` ```go gocron.WithStartAt(gocron.WithStartDateTime(futureTime)) ``` ```go gocron.WithEventListeners(...) ``` -------------------------------- ### OneTimeJobStartAtOption Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/types.md Defines options for when a one-time job should start. It can execute immediately, at a specific time, or at multiple specified times. ```APIDOC ## OneTimeJobStartAtOption ### Description Function that returns times for a one-time job. ### Values - `OneTimeJobStartImmediately()` - Execute now - `OneTimeJobStartDateTime(time.Time)` - Execute at specific time - `OneTimeJobStartDateTimes(...time.Time)` - Execute at multiple times ### Used by `OneTimeJob()` definition ``` -------------------------------- ### WithStartDateTimePast() Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Sets the start time to any point in time, including the past. Useful for backfilling schedules from a historical date. ```APIDOC ## WithStartDateTimePast() ### Description Sets the start time to any point in time, including the past. Useful for backfilling schedules from a historical date. ### Method func WithStartDateTimePast(start time.Time) StartAtOption ### Parameters #### Path Parameters - **start** (time.Time) - Required - Start time (can be past) ### Errors - `ErrWithStartDateTimePastZero` - If start time is zero - `ErrStartTimeLaterThanEndTime` - If start is after stop time ### Request Example ```go // Start from a week ago pastTime := time.Now().Add(-7*24*time.Hour) job, _ := scheduler.NewJob( gocron.DurationJob(1*time.Hour), gocron.NewTask(func() { fmt.Println("task") }), gocron.WithStartAt(gocron.WithStartDateTimePast(pastTime)), ) ``` ``` -------------------------------- ### Duration Job Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Shows how to schedule a job to run at a specific interval using a duration. This is useful for periodic tasks where exact cron timing is not required. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" ) func main() { // Create a new scheduler sscheduler, err := gocron.NewScheduler() if err != nil { panic(err) } // Schedule a job to run every 5 seconds _, err = scheduler.NewTask( gocron.NewDurationJob(5*time.Second, func() { fmt.Println("I will run every 5 seconds") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### Prometheus Monitor Implementation Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/monitors-and-logging.md An example implementation of the Monitor interface using Prometheus metrics. This monitor tracks job completion, failures, and execution time. ```go type PrometheusMonitor struct { jobsCompleted prometheus.Counter jobsFailed prometheus.Counter executionTime prometheus.Histogram } func (m *PrometheusMonitor) IncrementJob( id uuid.UUID, name string, tags []string, status JobStatus, ) { switch status { case gocron.Success: m.jobsCompleted.Inc() case gocron.Fail: m.jobsFailed.Inc() } } func (m *PrometheusMonitor) RecordJobTiming( startTime, endTime time.Time, id uuid.UUID, name string, tags []string, ) { duration := endTime.Sub(startTime) m.executionTime.Observe(duration.Seconds()) } ``` ```go scheduler, _ := gocron.NewScheduler( gocron.WithMonitor(myMonitor), ) ``` -------------------------------- ### Create Simple Duration Job with GoCron Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/README.md Schedules a job to run every 10 seconds. Requires initializing a scheduler and starting it. ```go scheduler, _ := gocron.NewScheduler() scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() { fmt.Println("Every 10 seconds") }), ) scheduler.Start() ``` -------------------------------- ### Get Last Job Run Start Time Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Returns the exact time when the job's most recent execution started. ```go startTime, err := job.LastRunStartedAt() if err != nil { log.Fatal(err) } fmt.Println("Started at:", startTime) ``` -------------------------------- ### Get Last Job Run Time Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Retrieve the timestamp when the job was last started. ```go job.LastRunStartedAt() ``` -------------------------------- ### Define a BeforeJobRuns Listener Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Create a listener using BeforeJobRuns to execute a function before a job starts. This is useful for logging or setup tasks. ```go listener := gocron.BeforeJobRuns(func(id uuid.UUID, name string) { log.Printf("Job %s starting", name) }) ``` -------------------------------- ### Get Next Job Run Time Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves the scheduled time for the next execution of a job. This method requires the scheduler to be started. ```go nextRun, err := job.NextRun() if err != nil { log.Fatal(err) } fmt.Println("Next run:", nextRun) ``` -------------------------------- ### Get Last Job Run Start Time (Deprecated) Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Deprecated: Use `LastRunStartedAt` instead. Returns the time when the job last began executing. ```go lastRun, err := job.LastRun() if err != nil { log.Fatal(err) } fmt.Println("Last run:", lastRun) ``` -------------------------------- ### Distributed Scheduling with Elector and Locker Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/INDEX.md Combines leader election (Elector) and distributed locking (Locker) for robust distributed scheduling. This example assumes a Redis setup for both. ```go package main import ( "fmt" "time" "github.com/go-co-op/gocron/v2" "github.com/redis/go-redis/v9" ) func main() { // Initialize Redis client redisClient := redis.NewClient(&redis.Options{ Addr: "localhost:6379", // Replace with your Redis address }) // Create a new scheduler with Elector and Locker sscheduler, err := gocron.NewScheduler( gocron.WithDistributedLocker(gocron.NewRedisLocker(redisClient)), gocron.WithDistributedElector(gocron.NewRedisElector(redisClient)), ) if err != nil { panic(err) } // Schedule a job _, err = scheduler.NewTask( gocron.NewDurationJob(time.Second, func() { fmt.Println("This job is running with leader election and locking") }), ) if err != nil { panic(err) } // Start the scheduler sscheduler.Start() // Keep the application running select {} } ``` -------------------------------- ### OneTimeJob Start Time in Past Error Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/errors.md This error occurs when attempting to schedule a OneTimeJob with a start time that has already passed, and the immediate option is not used. Ensure the start time is in the future. ```go pastTime := time.Now().Add(-1*time.Hour) job, err := scheduler.NewJob( gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(pastTime)), gocron.NewTask(func() {}), ) // err: "gocron: OneTimeJob: start must not be in the past" ``` -------------------------------- ### Configure Scheduler with Monitoring and Logging Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/README.md Initialize a scheduler with custom logger and monitor implementations for observing job execution and scheduler status. ```go scheduler, _ := gocron.NewScheduler( gocron.WithLogger(logger), gocron.WithMonitor(monitor), gocron.WithSchedulerMonitor(schedulerMonitor), ) ``` -------------------------------- ### WithStartAt() Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Wraps a start-time option for the job. It takes a StartAtOption as a parameter. ```APIDOC ## WithStartAt() ### Description Wraps a start-time option for the job. ### Method func WithStartAt(option StartAtOption) JobOption ### Parameters #### Path Parameters - **option** (StartAtOption) - Required - Start time option ### Request Example ```go job, _ := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() { fmt.Println("task") }), gocron.WithStartAt(gocron.WithStartImmediately()), ) ``` ``` -------------------------------- ### Create Task with Parameters Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Wrap a function with parameters using NewTask. Ensure the types and order of parameters match the function signature. ```go task := gocron.NewTask(func(msg string, count int) { for i := 0; i < count; i++ { fmt.Println(msg) } }, "Hello", 3) ``` -------------------------------- ### Import Google UUID Library Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/types.md Shows how to import the Google UUID library for use in your project. ```go import "github.com/google/uuid" ``` -------------------------------- ### BeforeJobRuns Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job-options.md Creates an EventListener that is triggered before a job starts executing. ```APIDOC ## BeforeJobRuns() ### Description Listener triggered before a job starts executing. ### Signature ```go func BeforeJobRuns( func(jobID uuid.UUID, jobName string), ) EventListener ``` ### Parameters #### callback - **callback** (`func(jobID uuid.UUID, jobName string)`) - Required - The function to execute before the job runs. ### Example ```go listener := gocron.BeforeJobRuns(func(id uuid.UUID, name string) { log.Printf("Job %s starting", name) }) ``` ``` -------------------------------- ### Create Task with Context and Parameters Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Combine context injection for cancellation with function parameters. The context must still be the first parameter. ```go task := gocron.NewTask(func(ctx context.Context, msg string) { for { select { case <-ctx.Done(): return case <-time.After(time.Second): fmt.Println(msg) } } }, "Heartbeat") ``` -------------------------------- ### Get Job Schedule Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Retrieve the scheduling definition for a specific job. ```go job.Schedule() ``` -------------------------------- ### Job Is Running Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Checks if a job is currently executing by comparing its start and completion times. ```APIDOC ## IsRunning() ### Description Returns whether the job is currently executing. Determined by comparing start and completion times. ### Returns - `bool` - True if job is currently running - `error` - `ErrJobNotFound` if job was removed ### Example ```go isRunning, err := job.IsRunning() if err != nil { log.Fatal(err) } if isRunning { fmt.Println("Job is currently executing") } ``` ``` -------------------------------- ### Job Last Run Started At Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves the exact time when the job's last execution began. ```APIDOC ## LastRunStartedAt() ### Description Returns the time when the job's last execution started. ### Returns - `time.Time` - Last run start time (zero time if never run) - `error` - `ErrJobNotFound` if job was removed ### Example ```go startTime, err := job.LastRunStartedAt() if err != nil { log.Fatal(err) } fmt.Println("Started at:", startTime) ``` ``` -------------------------------- ### Get Next N Job Runs Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Obtain the scheduled times for the next N executions of a job. ```go job.NextRuns(5) ``` -------------------------------- ### Set Monitor with WithMonitor() Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Use WithMonitor to attach a metrics monitor for collecting job execution statistics. ```go s, _ := gocron.NewScheduler( gocron.WithMonitor(myMonitor), ) ``` -------------------------------- ### Create Job with Parameters Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Define a job that accepts string and integer parameters. The task function will receive these values when the job executes. ```go // Job with parameters scheduler.NewJob( gocron.DurationJob(1*time.Minute), gocron.NewTask(func(name string, count int) { fmt.Printf("%s: %d\n", name, count) }, "Hello", 5), ) ``` -------------------------------- ### Retrieve All Jobs Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Get a slice of all jobs currently registered with the scheduler. Jobs are sorted by their unique IDs. ```go jobs := scheduler.Jobs() for _, job := range jobs { fmt.Printf("Job %s: %s\n", job.ID(), job.Name()) } ``` -------------------------------- ### Job Next Run Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves the time of the next scheduled execution for a job. This information is available only after the scheduler has been started. ```APIDOC ## NextRun() ### Description Returns the time of the next scheduled job run. Only available after the scheduler has been started. ### Returns - `time.Time` - Next run time (zero time if not scheduled yet) - `error` - `ErrJobNotFound` if job was removed ### Example ```go nextRun, err := job.NextRun() if err != nil { log.Fatal(err) } fmt.Println("Next run:", nextRun) ``` ``` -------------------------------- ### Create Scheduler: v1 vs v2 Source: https://github.com/go-co-op/gocron/blob/v2/migration_v1_to_v2.md v2 requires error checking during scheduler creation and no longer takes a timezone argument directly. Use WithLocation() for timezone configuration. ```go import "github.com/go-co-op/gocron" s := gocron.NewScheduler(time.UTC) ``` ```go import "github.com/go-co-op/gocron/v2" s, err := gocron.NewScheduler() if err != nil { panic(err) } ``` -------------------------------- ### WeeklyJob Interval Error Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/errors.md Triggers ErrWeeklyJobZeroInterval when the interval is 0. The interval for WeeklyJob must be greater than 0. ```go job, err := scheduler.NewJob( gocron.WeeklyJob(0, gocron.NewWeekdays(time.Monday), gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))), gocron.NewTask(func() {}), ) // err: "gocron: WeeklyJob: interval must be greater than 0" ``` -------------------------------- ### DurationJob Negative Interval Error Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/errors.md Triggers ErrDurationJobIntervalNegative when the duration is negative. Ensure the duration is a positive value. ```go job, err := scheduler.NewJob( gocron.DurationJob(-5*time.Second), gocron.NewTask(func() {}), ) // err: "gocron: DurationJob: time interval must be greater than 0" ``` -------------------------------- ### Create and Register New Job Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/scheduler.md Define and add a new job to the scheduler. Requires a job definition and a task, with optional configuration settings. ```go job, err := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func(msg string) { fmt.Println(msg) }, "Hello World"), gocron.WithName("hello_job"), gocron.WithTags("greeting"), ) if err != nil { log.Fatal(err) } fmt.Println("Job ID:", job.ID()) ``` -------------------------------- ### Create a New Logger Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/helper-functions.md Creates a logger instance with a specified minimum log level. Use LogLevelInfo for production environments and LogLevelDebug for development. ```go logger := gocron.NewLogger(gocron.LogLevelDebug) scheduler, _ := gocron.NewScheduler( gocron.WithLogger(logger), ) ``` ```go prodLogger := gocron.NewLogger(gocron.LogLevelInfo) scheduler, _ := gocron.NewScheduler( gocron.WithLogger(prodLogger), ) ``` ```go minimalLogger := gocron.NewLogger(gocron.LogLevelError) scheduler, _ := gocron.NewScheduler( gocron.WithLogger(minimalLogger), ) ``` -------------------------------- ### CronJob Parse Error Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/errors.md Triggers ErrCronJobParse when crontab syntax is invalid. Ensure crontab syntax is correct. ```go job, err := scheduler.NewJob( gocron.CronJob("invalid syntax", false), gocron.NewTask(func() {}), ) // err contains: "gocron: CronJob: crontab parse failure" ``` -------------------------------- ### Get Job Tags Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves all tags associated with a job. Tags are useful for organizing and managing jobs in batches. ```go tags := job.Tags() for _, tag := range tags { fmt.Println("Tag:", tag) } ``` -------------------------------- ### WithContext() Nil Context Error Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/errors.md Use `WithContext()` with a non-nil `context.Context`. Providing `nil` will trigger `ErrWithContextNil`. ```go job, err := scheduler.NewJob( gocron.DurationJob(10*time.Second), gocron.NewTask(func() {}), gocron.WithContext(nil), ) // err: "gocron: WithContext: context must not be nil" ``` -------------------------------- ### Configure Scheduler for Distributed Scheduling Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/README.md Set up a scheduler for distributed environments by providing implementations for leader election and distributed locking. ```go scheduler, _ := gocron.NewScheduler( gocron.WithDistributedElector(elector), gocron.WithDistributedLocker(locker), ) ``` -------------------------------- ### Get Job ID Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves the unique identifier for a job. This is useful for referencing specific jobs within the scheduler. ```go job, _ := scheduler.NewJob(...) id := job.ID() fmt.Println("Job ID:", id) ``` -------------------------------- ### DurationJob Zero Interval Error Example Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/errors.md Triggers ErrDurationJobIntervalZero when the duration is exactly 0. Use a positive duration for DurationJob. ```go job, err := scheduler.NewJob( gocron.DurationJob(0), gocron.NewTask(func() {}), ) // err: "gocron: DurationJob: time interval is 0" ``` -------------------------------- ### Get Job Name Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves the human-readable name of a job. If no name was explicitly set, it defaults to the fully-qualified function name. ```go name := job.Name() fmt.Println("Job name:", name) ``` -------------------------------- ### Create Task with No Parameters Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Use NewTask to wrap a function that takes no arguments. This is for simple, self-contained operations. ```go task := gocron.NewTask(func() { fmt.Println("Hello") }) ``` -------------------------------- ### Job Last Run (Deprecated) Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Retrieves the time when the job last started executing. This method is deprecated and `LastRunStartedAt` should be used instead. ```APIDOC ## LastRun() ### Description Deprecated: Use `LastRunStartedAt` instead. Returns the time when the job last started executing. ### Returns - `time.Time` - Last run start time (zero time if never run) - `error` - `ErrJobNotFound` if job was removed ### Example ```go lastRun, err := job.LastRun() if err != nil { log.Fatal(err) } fmt.Println("Last run:", lastRun) ``` ``` -------------------------------- ### Define Job with Arguments: v1 vs v2 Source: https://github.com/go-co-op/gocron/blob/v2/migration_v1_to_v2.md v2 allows passing arguments directly to the NewTask function when creating a job. ```go s.Every(1).Second().Do(taskFunc, arg1, arg2) ``` ```go j, err := s.NewJob( gocron.DurationJob(1*time.Second), gocron.NewTask(taskFunc, arg1, arg2), ) ``` -------------------------------- ### Check if Job is Running Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/api-reference/job.md Determines if a job is currently executing by comparing its start and completion times. Returns an error if the job has been removed. ```go isRunning, err := job.IsRunning() if err != nil { log.Fatal(err) } if isRunning { fmt.Println("Job is currently executing") } ``` -------------------------------- ### Create Scheduler Source: https://github.com/go-co-op/gocron/blob/v2/_autodocs/GETTING_STARTED.md Instantiate a new gocron scheduler. ```go gocron.NewScheduler() ```