Skip to content

Commit

Permalink
working to handle edge cases where a job can be run twice, unexpectedly
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnRoesler committed Jan 3, 2025
1 parent bf75107 commit 31b4eca
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
8 changes: 4 additions & 4 deletions job.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,15 +818,15 @@ func (d dailyJob) next(lastRun time.Time) time.Time {
}
firstPass = false

startNextDay := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(d.interval), 0, 0, 0, lastRun.Nanosecond(), lastRun.Location())
startNextDay := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(d.interval), 0, 0, 0, 0, lastRun.Location())
return d.nextDay(startNextDay, firstPass)
}

func (d dailyJob) nextDay(lastRun time.Time, firstPass bool) time.Time {
for _, at := range d.atTimes {
// sub the at time hour/min/sec onto the lastScheduledRun's values
// to use in checks to see if we've got our next run time
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day(), at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day(), at.Hour(), at.Minute(), at.Second(), 0, lastRun.Location())

if firstPass && atDate.After(lastRun) {
// checking to see if it is after i.e. greater than,
Expand Down Expand Up @@ -872,7 +872,7 @@ func (w weeklyJob) nextWeekDayAtTime(lastRun time.Time, firstPass bool) time.Tim
for _, at := range w.atTimes {
// sub the at time hour/min/sec onto the lastScheduledRun's values
// to use in checks to see if we've got our next run time
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(weekDayDiff), at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(weekDayDiff), at.Hour(), at.Minute(), at.Second(), 0, lastRun.Location())

if firstPass && atDate.After(lastRun) {
// checking to see if it is after i.e. greater than,
Expand Down Expand Up @@ -940,7 +940,7 @@ func (m monthlyJob) nextMonthDayAtTime(lastRun time.Time, days []int, firstPass
for _, at := range m.atTimes {
// sub the day, and the at time hour/min/sec onto the lastScheduledRun's values
// to use in checks to see if we've got our next run time
atDate := time.Date(lastRun.Year(), lastRun.Month(), day, at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
atDate := time.Date(lastRun.Year(), lastRun.Month(), day, at.Hour(), at.Minute(), at.Second(), 0, lastRun.Location())

if atDate.Month() != lastRun.Month() {
// this check handles if we're setting a day not in the current month
Expand Down
11 changes: 10 additions & 1 deletion scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ func (s *scheduler) selectExecJobsOutForRescheduling(id uuid.UUID) {
return
}

scheduleFrom := j.lastRun
var scheduleFrom time.Time
if len(j.nextScheduled) > 0 {
// always grab the last element in the slice as that is the furthest
// out in the future and the time from which we want to calculate
Expand Down Expand Up @@ -362,6 +362,15 @@ func (s *scheduler) selectExecJobsOutForRescheduling(id uuid.UUID) {
}
}

if slices.Contains(j.nextScheduled, next) {
// if the next value is a duplicate of what's already in the nextScheduled slice, for example:
// - the job is being rescheduled off the same next run value as before
// increment to the next, next value
for slices.Contains(j.nextScheduled, next) {
next = j.next(next)
}
}

// Clean up any existing timer to prevent leaks
if j.timer != nil {
j.timer.Stop()
Expand Down

0 comments on commit 31b4eca

Please sign in to comment.