Skip to Content

Scheduler

The scheduler package provides cron-based job scheduling for recurring tasks. It uses robfig/cron/v3  under the hood with second-precision support, job registration, and graceful shutdown.

Import

import "github.com/gofastadev/gofasta/pkg/scheduler"

Key Types

Job

The Job interface must be implemented by every cron job.

type Job interface { Name() string Run() }

Scheduler

type Scheduler struct { cron *cron.Cron logger *slog.Logger }

Key Functions

FunctionSignatureDescription
Newfunc New(logger *slog.Logger) *SchedulerCreates a new scheduler with second-precision cron support
Registerfunc (s *Scheduler) Register(schedule string, job Job) errorRegisters a job with a cron schedule expression
Startfunc (s *Scheduler) Start()Starts the scheduler (non-blocking)
Stopfunc (s *Scheduler) Stop()Waits for running jobs to finish, then stops the scheduler

Schedule Expressions

The scheduler supports standard cron expressions (with an optional seconds field) and predefined shortcuts.

ExpressionDescription
0 * * * * *Every minute (with seconds field)
0 0 * * * *Every hour
0 0 0 * * *Every day at midnight
0 */5 * * *Every 5 minutes (standard 5-field)
0 0 */6 * * *Every 6 hours (with seconds field)
0 9 * * 1-5Weekdays at 9:00 AM

Configuration

Job schedules are defined in config.yaml under the jobs: section:

jobs: - name: cleanup-sessions schedule: "*/5 * * * *" enabled: true - name: generate-reports schedule: "0 2 * * *" enabled: true - name: health-ping schedule: "*/30 * * * * *" enabled: false

The corresponding config type:

type JobConfig struct { Name string `koanf:"name"` Schedule string `koanf:"schedule"` Enabled bool `koanf:"enabled"` }

Usage

Implementing a Job

type CleanupSessionsJob struct { sessionStore *sessions.Store logger *slog.Logger } func (j *CleanupSessionsJob) Name() string { return "cleanup-sessions" } func (j *CleanupSessionsJob) Run() { j.logger.Info("cleaning up expired sessions") if err := j.sessionStore.Cleanup(); err != nil { j.logger.Error("session cleanup failed", "error", err) } }

Setting Up the Scheduler

The scheduler is typically configured in cmd/serve.go:

sched := scheduler.New(logger) // Register jobs err := sched.Register("*/5 * * * *", &CleanupSessionsJob{ sessionStore: sessionStore, logger: logger, }) if err != nil { log.Fatalf("failed to register job: %v", err) } err = sched.Register("0 2 * * *", &GenerateReportsJob{ reportService: reportService, logger: logger, }) if err != nil { log.Fatalf("failed to register job: %v", err) }

Starting and Stopping

// Start the scheduler (non-blocking) sched.Start() // Graceful shutdown quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit sched.Stop()
  • Queue — Queue long-running jobs instead of running them inline
  • Logger — Log scheduler activity
  • Health — Monitor scheduler status in health checks
Last updated on