### Create and Start Cron Scheduler in Go Source: https://context7.com/robfig/cron/llms.txt Demonstrates basic cron scheduler creation, adding a job, starting the scheduler, and graceful shutdown. The scheduler runs jobs in goroutines with thread-safe concurrent execution. Use cron.New() to instantiate, AddFunc() to register jobs, Start() to begin scheduling, and Stop() for graceful termination. ```go package main import ( "fmt" "time" "github.com/robfig/cron/v3" ) func main() { // Create a new cron scheduler with default settings c := cron.New() // Add a job that runs every minute c.AddFunc("* * * * *", func() { fmt.Println("Job runs every minute") }) // Start the scheduler in a goroutine c.Start() // Keep the program running time.Sleep(5 * time.Minute) // Stop the scheduler and wait for running jobs to complete ctx := c.Stop() <-ctx.Done() fmt.Println("Scheduler stopped gracefully") } ``` -------------------------------- ### Install and Import robfig/cron v3 in Go Source: https://github.com/robfig/cron/blob/master/README.md Demonstrates how to download and import the robfig/cron/v3 library in a Go program. It requires Go 1.11 or later due to the use of Go Modules. ```bash go get github.com/robfig/cron/v3@v3.0.0 ``` ```go import "github.com/robfig/cron/v3" ``` -------------------------------- ### Combine Job Wrappers: Recovery and SkipIfStillRunning (Go) Source: https://context7.com/robfig/cron/llms.txt Shows how to chain multiple job wrappers, such as `Recover` and `SkipIfStillRunning`, to create a robust execution policy. Wrappers can be applied globally during cron initialization or to individual jobs using `cron.NewChain`. This example also includes an individual job wrapped with `Recover` and `DelayIfStillRunning`, demonstrating panic handling and sequential execution for that specific job. ```go package main import ( "fmt" "log" "os" "time" "github.com/robfig/cron/v3" ) func main() { logger := cron.VerbosePrintfLogger( log.New(os.Stdout, "cron: ", log.LstdFlags)) // Combine multiple wrappers: recovery + skip if running c := cron.New( cron.WithChain( cron.Recover(logger), cron.SkipIfStillRunning(logger), ), cron.WithLogger(logger), ) // Add jobs with global wrappers c.AddFunc("@every 3s", func() { fmt.Println("Job with combined wrappers") time.Sleep(5 * time.Second) }) // Apply wrappers to individual job only job := cron.NewChain( cron.Recover(logger), cron.DelayIfStillRunning(logger), ).Then(cron.FuncJob(func() { fmt.Println("Individual wrapped job") if time.Now().Second()%10 == 0 { panic("Random panic!") } time.Sleep(2 * time.Second) })) c.Schedule(cron.Every(3*time.Second), job) c.Start() defer c.Stop() time.Sleep(30 * time.Second) } ``` -------------------------------- ### Configure Verbose Logging for Cron Jobs Source: https://github.com/robfig/cron/blob/master/README.md Demonstrates how to set up verbose logging for the cron scheduler using the `WithLogger` option. This example shows how to wrap a standard `*log.Logger` to provide leveled logging compatible with the `logr` interface, ensuring that `Info` logs are not discarded. ```go import "github.com/robfig/cron/v3" // Assuming 'logger' is a *log.Logger instance c := cron.New(cron.WithLogger(cron.VerbosePrintfLogger(logger))) ``` -------------------------------- ### Configure Cron with Seconds Field (Standard and Optional) Source: https://github.com/robfig/cron/blob/master/README.md Shows how to initialize a cron scheduler with different parser configurations. The first example enables the seconds field, which is required. The second example provides an optional seconds field, along with other standard cron fields, adhering to a more flexible parsing strategy. ```go c := cron.New(cron.WithSeconds()) ``` ```go c := cron.New(cron.WithParser(cron.NewParser(cron.SecondOptional | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor))) ``` -------------------------------- ### Manage Job Entries Dynamically with Robfig/Cron Source: https://context7.com/robfig/cron/llms.txt Illustrates how to dynamically manage scheduled jobs during runtime using the robfig/cron/v3 library. It covers adding jobs, retrieving their entry IDs, inspecting all active entries, getting specific entry details, and removing jobs. ```go package main import ( "fmt" "time" "github.com/robfig/cron/v3" ) func main() { c := cron.New() c.Start() defer c.Stop() // Add a job and get its entry ID id1, _ := c.AddFunc("@every 2s", func() { fmt.Println("Job 1: Still running") }) id2, _ := c.AddFunc("@every 3s", func() { fmt.Println("Job 2: Still running") }) fmt.Printf("Added job 1 with ID: %d\n", id1) fmt.Printf("Added job 2 with ID: %d\n", id2) time.Sleep(5 * time.Second) // Inspect all entries entries := c.Entries() fmt.Printf("\nTotal active jobs: %d\n", len(entries)) for _, entry := range entries { fmt.Printf("Entry ID: %d, Next run: %s, Prev run: %s\n", entry.ID, entry.Next.Format("15:04:05"), entry.Prev.Format("15:04:05")) } // Get specific entry entry := c.Entry(id1) if entry.Valid() { fmt.Printf("\nJob %d details - Next: %s\n", entry.ID, entry.Next) } // Remove job 1 fmt.Printf("\nRemoving job %d\n", id1) c.Remove(id1) time.Sleep(10 * time.Second) fmt.Printf("Remaining jobs: %d\n", len(c.Entries())) } ``` -------------------------------- ### Implement Complex Jobs with the Job Interface in Robfig/Cron Source: https://context7.com/robfig/cron/llms.txt Shows how to implement the `cron.Job` interface for creating jobs with state and complex logic. It provides examples of an `EmailJob` and a `DatabaseCleanupJob`, demonstrating how to add these custom jobs to the scheduler. ```go package main import ( "fmt" "sync/atomic" "time" "github.com/robfig/cron/v3" ) // EmailJob implements the cron.Job interface type EmailJob struct { recipient string counter int64 } func (e *EmailJob) Run() { count := atomic.AddInt64(&e.counter, 1) fmt.Printf("Sending email #%d to %s at %s\n", count, e.recipient, time.Now().Format("15:04:05")) } // DatabaseCleanupJob implements the cron.Job interface type DatabaseCleanupJob struct { tableName string retentionDays int } func (d *DatabaseCleanupJob) Run() { fmt.Printf("Cleaning up %s table (retention: %d days)\n", d.tableName, d.retentionDays) // Simulate database cleanup work time.Sleep(100 * time.Millisecond) fmt.Println("Cleanup complete") } func main() { c := cron.New() // Add job using AddJob method emailJob := &EmailJob{recipient: "user@example.com"} _, err := c.AddJob("@every 5s", emailJob) if err != nil { fmt.Println("Error:", err) return } // Add another job instance cleanupJob := &DatabaseCleanupJob{ tableName: "audit_logs", retentionDays: 90, } c.AddJob("0 2 * * *", cleanupJob) // Run at 2 AM daily c.Start() time.Sleep(20 * time.Second) c.Stop() } ``` -------------------------------- ### Custom Business Hours Schedule Implementation (Go) Source: https://context7.com/robfig/cron/llms.txt Provides an example of implementing a custom schedule by satisfying the `cron.Schedule` interface. The `BusinessHoursSchedule` struct ensures jobs only run between 9 AM and 5 PM, Monday through Friday, by calculating the `Next` valid execution time. This custom schedule can be used with `cron.New()`. The example also shows how to inspect the next scheduled run time of entries. ```go package main import ( "fmt" "time" "github.com/robfig/cron/v3" ) // BusinessHoursSchedule runs jobs only during business hours (9 AM - 5 PM, Mon-Fri) type BusinessHoursSchedule struct { interval time.Duration } func (s BusinessHoursSchedule) Next(t time.Time) time.Time { next := t.Add(s.interval) // Skip weekends for next.Weekday() == time.Saturday || next.Weekday() == time.Sunday { next = time.Date(next.Year(), next.Month(), next.Day()+1, 9, 0, 0, 0, next.Location()) } // Ensure within business hours (9 AM - 5 PM) hour := next.Hour() if hour < 9 { next = time.Date(next.Year(), next.Month(), next.Day(), 9, 0, 0, 0, next.Location()) } else if hour >= 17 { // Move to next business day at 9 AM next = time.Date(next.Year(), next.Month(), next.Day()+1, 9, 0, 0, 0, next.Location()) // Check if next day is weekend for next.Weekday() == time.Saturday || next.Weekday() == time.Sunday { next = next.AddDate(0, 0, 1) } } return next } func main() { c := cron.New() // Use custom schedule schedule := BusinessHoursSchedule{interval: 30 * time.Minute} c.Schedule(schedule, cron.FuncJob(func() { fmt.Printf("Business hours job at %s\n", time.Now().Format("Mon 15:04:05")) })) c.Start() defer c.Stop() // Inspect when next run will be entries := c.Entries() if len(entries) > 0 { fmt.Printf("Next scheduled run: %s\n", entries[0].Next.Format("Mon Jan 2 15:04:05 2006")) } select {} } ``` -------------------------------- ### Implement Panic Recovery Wrapper in Robfig/Cron Source: https://context7.com/robfig/cron/llms.txt Demonstrates how to use the `cron.Recover` wrapper to prevent panics in scheduled jobs from crashing the entire scheduler. It shows configuring a logger and chaining the recover middleware with other options. ```go package main import ( "fmt" "log" "os" "github.com/robfig/cron/v3" ) func main() { // Create custom logger logger := cron.VerbosePrintfLogger( log.New(os.Stdout, "cron: ", log.LstdFlags)) // Create cron with panic recovery wrapper c := cron.New( cron.WithChain( cron.Recover(logger), ), cron.WithLogger(logger), ) // This job will panic but won't crash the scheduler c.AddFunc("@every 3s", func() { fmt.Println("About to panic...") panic("Something went wrong!") }) // This job will continue running normally c.AddFunc("@every 2s", func() { fmt.Println("Normal job running fine") }) c.Start() defer c.Stop() // The scheduler keeps running despite panics select {} } ``` -------------------------------- ### Use Predefined Schedules and Fixed Intervals in Go Source: https://context7.com/robfig/cron/llms.txt Demonstrates convenient predefined schedule descriptors (@yearly, @monthly, @weekly, @daily, @hourly) and fixed-interval scheduling using @every syntax with various time durations. These descriptors simplify common scheduling patterns and provide readable alternatives to cron expressions. ```go package main import ( "fmt" "github.com/robfig/cron/v3" ) func main() { c := cron.New() // Predefined descriptors c.AddFunc("@yearly", func() { fmt.Println("Runs once a year at midnight on January 1st") }) c.AddFunc("@monthly", func() { fmt.Println("Runs at midnight on the first day of every month") }) c.AddFunc("@weekly", func() { fmt.Println("Runs at midnight between Saturday and Sunday") }) c.AddFunc("@daily", func() { fmt.Println("Runs every day at midnight") }) c.AddFunc("@hourly", func() { fmt.Println("Runs at the beginning of every hour") }) // Fixed interval scheduling c.AddFunc("@every 1h30m", func() { fmt.Println("Runs every 1 hour and 30 minutes") }) c.AddFunc("@every 5m", func() { fmt.Println("Runs every 5 minutes") }) c.AddFunc("@every 10s", func() { fmt.Println("Runs every 10 seconds") }) c.Start() defer c.Stop() select {} } ``` -------------------------------- ### Add Jobs with Standard Cron Expressions in Go Source: https://context7.com/robfig/cron/llms.txt Shows how to schedule jobs using standard five-field cron syntax with various patterns including specific times, day ranges, and intervals. AddFunc() returns an entry ID for tracking and managing scheduled jobs. Demonstrates multiple scheduling patterns: hourly at specific minutes, weekday-specific times, and monthly intervals. ```go package main import ( "fmt" "log" "github.com/robfig/cron/v3" ) func main() { c := cron.New() // Run at 30 minutes past every hour entryID1, err := c.AddFunc("30 * * * *", func() { fmt.Println("Runs at 30 minutes past every hour") }) if err != nil { log.Fatal(err) } fmt.Printf("Added job with ID: %d\n", entryID1) // Run every weekday at 9 AM c.AddFunc("0 9 * * MON-FRI", func() { fmt.Println("Good morning! It's a weekday.") }) // Run on the 1st and 15th of every month at midnight c.AddFunc("0 0 1,15 * *", func() { fmt.Println("Bi-monthly report generation") }) // Run every 6 hours c.AddFunc("0 */6 * * *", func() { fmt.Println("Runs at 00:00, 06:00, 12:00, 18:00") }) c.Start() defer c.Stop() select {} // Block forever } ``` -------------------------------- ### Queue Jobs with DelayIfStillRunning (Go) Source: https://context7.com/robfig/cron/llms.txt Illustrates the use of the DelayIfStillRunning wrapper to queue jobs. If a job is still running when the next scheduled execution is due, the new execution will wait until the previous one completes. This ensures sequential execution of potentially long-running tasks. Requires a logger. ```go package main import ( "fmt" "log" "os" "time" "github.com/robfig/cron/v3" ) func main() { logger := cron.VerbosePrintfLogger( log.New(os.Stdout, "cron: ", log.LstdFlags)) // Apply DelayIfStillRunning wrapper c := cron.New( cron.WithChain( cron.DelayIfStillRunning(logger), ), cron.WithLogger(logger), ) jobCount := 0 // Job scheduled every 2 seconds but takes 3 seconds to run c.AddFunc("@every 2s", func() { jobCount++ fmt.Printf("Job #%d started at %s\n", jobCount, time.Now().Format("15:04:05")) time.Sleep(3 * time.Second) fmt.Printf("Job #%d finished at %s\n", jobCount, time.Now().Format("15:04:05")) }) c.Start() defer c.Stop() // Jobs will be delayed and run sequentially time.Sleep(20 * time.Second) } ``` -------------------------------- ### Custom Logger Integration for Cron Scheduler in Go Source: https://context7.com/robfig/cron/llms.txt Shows how to integrate custom logging solutions with the cron scheduler in Go. It includes a `CustomLogger` type that implements the `cron.Logger` interface and demonstrates using `cron.VerbosePrintfLogger` and `cron.DiscardLogger`. This allows for flexible logging configurations, from detailed output to completely silent operation. ```go package main import ( "fmt" "log" "os" "github.com/robfig/cron/v3" ) // CustomLogger implements the cron.Logger interface type CustomLogger struct { logger *log.Logger } func (cl CustomLogger) Info(msg string, keysAndValues ...interface{}) { cl.logger.Printf("[INFO] %s %v", msg, keysAndValues) } func (cl CustomLogger) Error(err error, msg string, keysAndValues ...interface{}) { cl.logger.Printf("[ERROR] %s: %v %v", msg, err, keysAndValues) } func main() { // Create custom logger customLogger := CustomLogger{ logger: log.New(os.Stdout, "CUSTOM: ", log.LstdFlags), } // Use verbose printf logger verboseLogger := cron.VerbosePrintfLogger( log.New(os.Stdout, "cron: ", log.LstdFlags)) // Create cron with custom logger c := cron.New( cron.WithLogger(customLogger), cron.WithChain(cron.Recover(verboseLogger)), ) c.AddFunc("@every 5s", func() { fmt.Println("Job executed") }) // Silent logger that discards all logs c2 := cron.New(cron.WithLogger(cron.DiscardLogger)) c2.AddFunc("@every 3s", func() { fmt.Println("Silent job - no logs") }) c.Start() c2.Start() defer func() { c.Stop() c2.Stop() }() select {} } ``` -------------------------------- ### Enable Panic Recovery for Cron Jobs Source: https://github.com/robfig/cron/blob/master/README.md Illustrates how to configure the cron scheduler to recover from panics that occur during job execution. This is achieved using the `WithChain` option and the `Recover` function, which can optionally take a logger. ```go import "github.com/robfig/cron/v3" // Assuming 'logger' is a valid logr.Logger instance c := cron.New(cron.WithChain(cron.Recover(logger))) // or use cron.DefaultLogger ``` -------------------------------- ### Custom Cron Parser for Non-Standard Formats in Go Source: https://context7.com/robfig/cron/llms.txt Demonstrates creating a custom cron parser to support different cron expression formats, including optional seconds and descriptor fields. It shows how to add jobs with and without seconds, and how to create parsers for date-only specifications. This is useful when dealing with cron formats that deviate from the standard. ```go package main import ( "fmt" "log" "github.com/robfig/cron/v3" ) func main() { // Create parser with custom options // Format: second (optional) minute hour day month weekday parser := cron.NewParser( cron.SecondOptional | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor, ) c := cron.New(cron.WithParser(parser)) // Can now use expressions with or without seconds c.AddFunc("0 30 * * * *", func() { fmt.Println("With seconds: runs at 30 minutes") }) c.AddFunc("45 * * * *", func() { fmt.Println("Without seconds: runs at 45 minutes") }) // Parser for day/month/weekday only (no time fields) dateOnlyParser := cron.NewParser( cron.Dom | cron.Month | cron.DowOptional, ) c2 := cron.New(cron.WithParser(dateOnlyParser)) // Just specify day of month, month, and optionally day of week _, err := c2.AddFunc("15 */2", func() { fmt.Println("Runs on 15th of every other month") }) if err != nil { log.Fatal(err) } c.Start() c2.Start() defer func() { c.Stop() c2.Stop() }() select {} } ``` -------------------------------- ### Enable Seconds Field with WithSeconds Option in Go Source: https://context7.com/robfig/cron/llms.txt Shows how to enable seconds-level precision in cron expressions using the WithSeconds() option, changing the format from five fields to six fields. This allows scheduling jobs at second-level intervals, useful for high-frequency or precise timing requirements. ```go package main import ( "fmt" "time" "github.com/robfig/cron/v3" ) func main() { // Create cron with seconds field enabled (6 fields total) c := cron.New(cron.WithSeconds()) // Now the format is: second minute hour day month weekday c.AddFunc("0 30 * * * *", func() { fmt.Println("Runs at 30 minutes and 0 seconds past every hour") }) c.AddFunc("*/15 * * * * *", func() { fmt.Println("Runs every 15 seconds") }) c.AddFunc("0 0 12 * * MON-FRI", func() { fmt.Println("Runs at exactly noon on weekdays") }) // Job that runs every 5 seconds c.AddFunc("*/5 * * * * *", func() { fmt.Printf("Tick: %s\n", time.Now().Format("15:04:05")) }) c.Start() time.Sleep(1 * time.Minute) c.Stop() } ``` -------------------------------- ### Schedule Jobs in Specific Timezones with Robfig/Cron Source: https://context7.com/robfig/cron/llms.txt Demonstrates how to schedule jobs in specific timezones using the `cron.WithLocation` option or the `CRON_TZ` and `TZ` prefixes. It shows setting a default timezone and overriding it for individual jobs. ```go package main import ( "fmt" "time" "github.com/robfig/cron/v3" ) func main() { // Set default timezone to UTC for all jobs utcLocation, _ := time.LoadLocation("UTC") c := cron.New(cron.WithLocation(utcLocation)) // This job runs at 6 AM UTC c.AddFunc("0 6 * * *", func() { fmt.Println("6 AM UTC job") }) // Override timezone for specific job using CRON_TZ c.AddFunc("CRON_TZ=America/New_York 0 9 * * *", func() { fmt.Println("9 AM Eastern Time job") }) c.AddFunc("CRON_TZ=Asia/Tokyo 0 18 * * *", func() { fmt.Println("6 PM Tokyo time job") }) // Legacy TZ= prefix is also supported c.AddFunc("TZ=Europe/London 0 12 * * *", func() { fmt.Println("Noon London time job") }) c.Start() defer c.Stop() // Display current timezone info fmt.Printf("Default location: %s\n", c.Location()) select {} } ``` -------------------------------- ### Prevent Concurrent Job Execution with SkipIfStillRunning (Go) Source: https://context7.com/robfig/cron/llms.txt Demonstrates how to use the SkipIfStillRunning wrapper from the robfig/cron/v3 library to prevent a job from running if a previous instance is still executing. It requires a logger for verbose output. Jobs that would overlap will be skipped and logged. ```go package main import ( "fmt" "log" "os" "time" "github.com/robfig/cron/v3" ) func main() { logger := cron.VerbosePrintfLogger( log.New(os.Stdout, "cron: ", log.LstdFlags)) // Apply SkipIfStillRunning to all jobs c := cron.New( cron.WithChain( cron.SkipIfStillRunning(logger), ), cron.WithLogger(logger), ) // Long-running job that takes 5 seconds c.AddFunc("@every 2s", func() { fmt.Println("Starting long job...") time.Sleep(5 * time.Second) fmt.Println("Long job completed") }) c.Start() defer c.Stop() // You'll see skips logged when the job is still running time.Sleep(15 * time.Second) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.