package task import ( "context" "fmt" "time" cron "github.com/robfig/cron/v3" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) var l zerolog.Logger var clog = mylogger{} var c *cron.Cron func init() { // viper.Set("task.runner", 5) Reporter = make(chan *Report) } func Init() { l = log.With().Str("mod", "task").Logger() c = cron.New( cron.WithLogger(&clog), cron.WithChain(func(j cron.Job) cron.Job { t, ok := j.(*_task) if ok { l.Debug().Str("taskname", t.Task.Name).Msg("") } return j }), cron.WithLocation(time.Local)) } type Task struct { Name string ID string Description string Group string // Func is the stored function that will be called with the args, // and a interface to carry value will be provided as the first argument // args will be passed after carry, in order to normalize, // it is suggested to use strings or other simple types Func func(c *interface{}, args ...interface{}) error `json:"-"` } type _task struct { Task *Task id cron.EntryID args []interface{} spec string once bool // carry value to the next run. Should be modified from the Task.Func carry *interface{} } func (t *_task) Run() { if t.carry == nil { t.carry = new(interface{}) } defer func() { if err := recover(); err != nil { log.Error().Str("error", fmt.Sprint(err)).Msg("") } else if t.once { c.Remove(t.id) } }() if err := t.Task.Func(t.carry, t.args...); err != nil { log.Error().Err(err).Str("taskname", t.Task.Name).Msg("") Reporter <- &Report{ Entry: t.id, Name: t.Task.Name, ID: t.Task.ID, Description: t.Task.Description, Group: t.Task.Group, Spec: t.spec, Once: t.once, Args: t.args, Carry: t.carry, Error: err, } } } func Start() { c.Start() } func Stop() context.Context { return c.Stop() }