1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
package agent
import (
"context"
"github.com/robfig/cron/v3"
)
type Job interface {
// Run executes the cron task. It should cancel whatever it
// is doing upon receiving a signal from ctx.Done.
Run(context.Context)
}
// CronScheduler can run tasks on a cron schedule, with cancellation.
type CronScheduler struct {
runner *cron.Cron
}
func NewCronScheduler() *CronScheduler {
return &CronScheduler{runner: cron.New()}
}
func (s *CronScheduler) Run(ctx context.Context) {
s.runner.Start()
<-ctx.Done()
stopCtx := s.runner.Stop()
// Block until all jobs are stopped
<-stopCtx.Done()
}
// bit of a hack so that we can pass a context into cron.Schedule
type jobWrapper struct {
ctx context.Context
runFunc func(context.Context)
}
func (j *jobWrapper) Run() {
j.runFunc(j.ctx)
}
func (s *CronScheduler) Schedule(ctx context.Context, schedule cron.Schedule, job Job) {
wrapper := &jobWrapper{
ctx: ctx,
runFunc: job.Run,
}
s.runner.Schedule(schedule, wrapper)
}
|