cron.go

 1// Package cron provides scheduled task management functionality.
 2package cron
 3
 4import (
 5	"context"
 6	"time"
 7
 8	"github.com/charmbracelet/log/v2"
 9	"github.com/robfig/cron/v3"
10)
11
12// Scheduler is a cron-like job scheduler.
13type Scheduler struct {
14	*cron.Cron
15}
16
17// cronLogger is a wrapper around the logger to make it compatible with the
18// cron logger.
19type cronLogger struct {
20	logger *log.Logger
21}
22
23// Info logs routine messages about cron's operation.
24func (l cronLogger) Info(msg string, keysAndValues ...interface{}) {
25	l.logger.Debug(msg, keysAndValues...)
26}
27
28// Error logs an error condition.
29func (l cronLogger) Error(err error, msg string, keysAndValues ...interface{}) {
30	l.logger.Error(msg, append(keysAndValues, "err", err)...)
31}
32
33// NewScheduler returns a new Cron.
34func NewScheduler(ctx context.Context) *Scheduler {
35	logger := cronLogger{log.FromContext(ctx).WithPrefix("cron")}
36	return &Scheduler{
37		Cron: cron.New(cron.WithLogger(logger)),
38	}
39}
40
41// Shutdown gracefully shuts down the Scheduler.
42func (s *Scheduler) Shutdown() {
43	ctx, cancel := context.WithTimeout(s.Stop(), 30*time.Second)
44	defer func() { cancel() }()
45	<-ctx.Done()
46}
47
48// Start starts the Scheduler.
49func (s *Scheduler) Start() {
50	s.Cron.Start()
51}
52
53// AddFunc adds a job to the Scheduler.
54func (s *Scheduler) AddFunc(spec string, fn func()) (int, error) {
55	id, err := s.Cron.AddFunc(spec, fn)
56	return int(id), err
57}
58
59// Remove removes a job from the Scheduler.
60func (s *Scheduler) Remove(id int) {
61	s.Cron.Remove(cron.EntryID(id))
62}