Help us shape the future of Go! Take the 2026 Go Developer Survey

scheduler

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 7 Imported by: 0

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)

func (BackoffTask) Execute

func (bt BackoffTask) Execute(ctx context.Context) error

Execute implements workerpool.Task with exponential backoff.

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 New

func New() Scheduler

New creates a scheduler with default configuration.

func NewWithConfig

func NewWithConfig(cfg Config) Scheduler

NewWithConfig creates a scheduler with custom configuration.

type Task

type Task struct {
	ID       string
	RunAt    time.Time
	Interval time.Duration // Zero for one-time tasks
	Created  time.Time
}

Task represents a scheduled task.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL