cron
cron copied to clipboard
Adding entry directly
At the moment adding new entries is only possible by using one of the functions:
func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error)
func (c *Cron) AddJob(spec string, cmd Job) (EntryID, error)
func (c *Cron) Schedule(schedule Schedule, cmd Job) EntryID
which delegate work to one another.
Adding another function, which accepts a raw Entry
would allow certain scenarios that are impossible at the moment.
For example, if we wanted to restore a schedule from external storage where we saved the last/next execution time currently we'd have to write a separate Schedule
implementation.
Even though the check would be trivial, I feel that this should belong to the cron implementation, since most of the code is already there.
I'll be glad to dontate some code since I'll be adding similar code to my fork either way.
I'm not sure I fully understand the use case for accepting an Entry directly.. it seems like the Schedule and Job are indeed the only things that the user needs to / should provide. What is the scenario where the Last/Next execution time needs to be restored from storage instead of being computed from the Schedule?
If I understood correctly the author wants to restart the process but keep the state of the entries, such as last execution, or even set it manually. if this is the case I am interested in this feature as well
I managed to deal with this with the following:
Create a custom Schedule that wraps the default schedule so we can use use custom values when calculating the next execution time
package myPackage
import (
"sync"
"time"
"github.com/robfig/cron/v3"
)
var _ cron.Schedule = (*cronScheduleCalculator)(nil)
type cronScheduleCalculator struct {
LastRun time.Time
BaseSchedule cron.Schedule
HadStartedMutex sync.Mutex
HadStarted bool
}
func cronScheduleCalculatorNew(baseSchedule cron.Schedule, lastRun time.Time) cron.Schedule {
return &cronScheduleCalculator{
LastRun: lastRun,
BaseSchedule: baseSchedule,
HadStartedMutex: sync.Mutex{},
HadStarted: false,
}
}
func (calc *cronScheduleCalculator) Next(time time.Time) time.Time {
calc.HadStartedMutex.Lock()
defer calc.HadStartedMutex.Unlock()
if !calc.HadStarted {
calc.HadStarted = true
if !calc.LastRun.IsZero() {
return calc.BaseSchedule.Next(calc.LastRun)
}
}
return calc.BaseSchedule.Next(time)
}
And then use this when calling myCron.Schedule
schedule, _ := cronParser.Parse(cronExp)
schedule = cronScheduleCalculatorNew(schedule, lastRun)
entryId := myCron.Schedule(schedule, job)