Documentation
¶
Overview ¶
Package scheduler provides task scheduling with support for delayed execution, repeating tasks, and cron expressions.
Basic usage:
s := scheduler.New()
s.Start()
defer func() { <-s.Stop() }()
task := workerpool.TaskFunc(func(ctx context.Context) error {
fmt.Println("Hello, world!")
return nil
})
// Run once after 5 seconds
s.ScheduleAfter("hello", task, 5*time.Second)
// Run every minute
s.ScheduleRepeating("heartbeat", task, time.Minute)
// Run using cron expression
s.ScheduleCron("daily", "0 0 * * *", task)
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BackoffTask ¶
type BackoffTask struct {
Task workerpool.Task
MaxRetries int
InitialDelay time.Duration
MaxDelay time.Duration
}
BackoffTask wraps a task with retry logic.
Example ¶
// Task that fails a few times then succeeds
attempts := 0
unreliableTask := workerpool.TaskFunc(func(_ context.Context) error {
attempts++
if attempts < 3 {
return fmt.Errorf("temporary failure (attempt %d)", attempts)
}
fmt.Println("Task succeeded!")
return nil
})
// Wrap with retry logic
resilientTask := BackoffTask{
Task: unreliableTask,
MaxRetries: 5,
InitialDelay: 10 * time.Millisecond,
MaxDelay: 1 * time.Second,
}
ctx := context.Background()
if err := resilientTask.Execute(ctx); err != nil {
log.Printf("Task failed: %v", err)
}
Output: Task succeeded!
Example (Production) ¶
// Example of using BackoffTask for resilient operations
unreliableAPI := workerpool.TaskFunc(func(_ context.Context) error {
// Simulate unreliable external API call
if time.Now().UnixNano()%3 == 0 {
return nil // Success
}
return context.DeadlineExceeded // Simulate timeout
})
// Wrap with exponential backoff retry logic
resilientTask := BackoffTask{
Task: unreliableAPI,
MaxRetries: 3,
InitialDelay: 100 * time.Millisecond,
MaxDelay: time.Second,
}
scheduler := New()
defer func() { <-scheduler.Stop() }()
_ = scheduler.Start()
// Schedule the resilient task
_ = scheduler.ScheduleAfter("api-call", resilientTask, time.Millisecond)
// Wait for execution
time.Sleep(100 * time.Millisecond)
type Config ¶
type Config struct {
WorkerPool workerpool.Pool
Location *time.Location
TickInterval time.Duration
MaxTasks int
}
Config holds scheduler configuration.
type Scheduler ¶
type Scheduler interface {
// Basic scheduling
Schedule(id string, task workerpool.Task, runAt time.Time) error
ScheduleAfter(id string, task workerpool.Task, delay time.Duration) error
ScheduleRepeating(id string, task workerpool.Task, interval time.Duration) error
// Cron scheduling
ScheduleCron(id string, cronExpr string, task workerpool.Task) error
// Task management
Cancel(id string) bool
CancelAll()
List() []Task
// Lifecycle
Start() error
Stop() <-chan struct{}
}
Scheduler provides task scheduling with cron support.
Example (Basic) ¶
// Create scheduler
scheduler := New()
defer func() { <-scheduler.Stop() }()
// Start the scheduler
_ = scheduler.Start()
// Simple task
task := workerpool.TaskFunc(func(_ context.Context) error {
fmt.Println("Task executed")
return nil
})
// Schedule task to run in 100ms
_ = scheduler.ScheduleAfter("simple-task", task, 100*time.Millisecond)
time.Sleep(200 * time.Millisecond)
Output: Task executed
Example (Cron) ¶
scheduler := New()
defer func() { <-scheduler.Stop() }()
_ = scheduler.Start()
task := workerpool.TaskFunc(func(_ context.Context) error {
fmt.Println("Daily backup started")
return nil
})
// Run at 2:30 AM every day
if err := scheduler.ScheduleCron("backup", "0 30 2 * * *", task); err != nil {
log.Fatal(err)
}
// In real usage, this would run continuously
Example (Production) ¶
// Create a production-ready scheduler with custom config
config := Config{
WorkerPool: workerpool.New(4, 100), //nolint:staticcheck // Example code
TickInterval: 100 * time.Millisecond, // Check every 100ms
MaxTasks: 1000, // Limit to 1000 concurrent tasks
}
scheduler := NewWithConfig(config)
defer func() { <-scheduler.Stop() }()
_ = scheduler.Start()
// Example: Database cleanup task
cleanupTask := workerpool.TaskFunc(func(ctx context.Context) error {
log.Println("Running database cleanup...")
// Simulate cleanup work
select {
case <-time.After(50 * time.Millisecond):
log.Println("Database cleanup completed")
return nil
case <-ctx.Done():
return ctx.Err()
}
})
// Example: Health check task
healthTask := workerpool.TaskFunc(func(_ context.Context) error {
log.Println("Running health check...")
// Simulate health check
return nil
})
// Example: Report generation task
reportTask := workerpool.TaskFunc(func(_ context.Context) error {
log.Println("Generating daily report...")
return nil
})
// Schedule cleanup to run every hour
_ = scheduler.ScheduleRepeating("db-cleanup", cleanupTask, time.Hour)
// Schedule health check every 30 seconds
_ = scheduler.ScheduleRepeating("health-check", healthTask, 30*time.Second)
// Schedule daily report at 9 AM using cron
_ = scheduler.ScheduleCron("daily-report", "0 0 9 * * *", reportTask)
// Schedule one-time maintenance task
maintenanceTask := workerpool.TaskFunc(func(_ context.Context) error {
log.Println("Running maintenance...")
return nil
})
_ = scheduler.ScheduleAfter("maintenance", maintenanceTask, 5*time.Minute)
// In production, you'd run this indefinitely
// select {}
// For this example, just run briefly to demonstrate functionality
time.Sleep(200 * time.Millisecond)
Example (Repeating) ¶
scheduler := New()
defer func() { <-scheduler.Stop() }()
_ = scheduler.Start()
var count int64
task := workerpool.TaskFunc(func(_ context.Context) error {
current := atomic.AddInt64(&count, 1)
fmt.Printf("Execution %d\n", current)
return nil
})
// Run every 75ms
_ = scheduler.ScheduleRepeating("counter", task, 75*time.Millisecond)
time.Sleep(300 * time.Millisecond)
Output: Execution 1 Execution 2 Execution 3
Example (WebServerTasks) ¶
scheduler := New()
defer func() { <-scheduler.Stop() }()
_ = scheduler.Start()
// Cleanup old sessions every hour
cleanupTask := workerpool.TaskFunc(func(_ context.Context) error {
fmt.Println("Cleaning up expired sessions...")
// Your cleanup logic here
return nil
})
_ = scheduler.ScheduleCron("cleanup", "@hourly", cleanupTask)
// Health check every 30 seconds
healthTask := workerpool.TaskFunc(func(_ context.Context) error {
fmt.Println("Running health check...")
// Your health check logic here
return nil
})
_ = scheduler.ScheduleRepeating("health", healthTask, 30*time.Second)
// Send metrics report every 5 minutes
metricsTask := workerpool.TaskFunc(func(_ context.Context) error {
fmt.Println("Sending metrics report...")
// Your metrics reporting logic here
return nil
})
_ = scheduler.ScheduleRepeating("metrics", metricsTask, 5*time.Minute)
// In a real server, you'd run indefinitely
// select {}
func NewWithConfig ¶
NewWithConfig creates a scheduler with custom configuration.
Click to show internal directories.
Click to hide internal directories.