scheduler

package
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Feb 15, 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