66 lines
1.0 KiB
Go
66 lines
1.0 KiB
Go
package worker
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
type Job interface {
|
|
Name() string
|
|
Run(context.Context) error
|
|
}
|
|
|
|
type Logger func(format string, args ...any)
|
|
|
|
type Runner struct {
|
|
jobs []Job
|
|
interval time.Duration
|
|
logger Logger
|
|
}
|
|
|
|
func NewRunner(jobs []Job, interval time.Duration, logger Logger) *Runner {
|
|
return &Runner{
|
|
jobs: append([]Job(nil), jobs...),
|
|
interval: interval,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
func (r *Runner) Start(ctx context.Context) {
|
|
if r == nil {
|
|
return
|
|
}
|
|
go func() {
|
|
r.runOnce(ctx)
|
|
if ctx.Err() != nil || r.interval <= 0 {
|
|
return
|
|
}
|
|
|
|
ticker := time.NewTicker(r.interval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
r.runOnce(ctx)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (r *Runner) runOnce(ctx context.Context) {
|
|
for _, job := range r.jobs {
|
|
if ctx.Err() != nil {
|
|
return
|
|
}
|
|
if job == nil {
|
|
continue
|
|
}
|
|
if err := job.Run(ctx); err != nil && ctx.Err() == nil && r.logger != nil {
|
|
r.logger("%s: %v", job.Name(), err)
|
|
}
|
|
}
|
|
}
|