diff --git a/README.md b/README.md index 953a1df9..4a1de758 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Jobs can be run every x weeks on specific days of the week and at specific times - [**Monthly**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#MonthlyJob): Jobs can be run every x months on specific days of the month and at specific times. - [**One time**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#OneTimeJob): -Jobs can be run once at a specific time. These are non-recurring jobs. +Jobs can be run at specific time(s) (either once or many times). ### Concurrency Limits Jobs can be limited individually or across the entire scheduler. diff --git a/job.go b/job.go index 7f1f2c40..5b0302c4 100644 --- a/job.go +++ b/job.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "math/rand" - "sort" "strings" "time" @@ -448,11 +447,9 @@ type oneTimeJobDefinition struct { func (o oneTimeJobDefinition) setup(j *internalJob, _ *time.Location, now time.Time) error { sortedTimes := o.startAt(j) - sort.Slice(sortedTimes, func(i, j int) bool { - return sortedTimes[i].Before(sortedTimes[j]) - }) + slices.SortStableFunc(sortedTimes, ascendingTime) // keep only schedules that are in the future - idx, found := slices.BinarySearchFunc(sortedTimes, now, timeCmp()) + idx, found := slices.BinarySearchFunc(sortedTimes, now, ascendingTime) if found { idx++ } @@ -499,18 +496,6 @@ func OneTimeJob(startAt OneTimeJobStartAtOption) JobDefinition { } } -func timeCmp() func(element time.Time, target time.Time) int { - return func(element time.Time, target time.Time) int { - if element.Equal(target) { - return 0 - } - if element.Before(target) { - return -1 - } - return 1 - } -} - // ----------------------------------------------- // ----------------------------------------------- // ----------------- Job Options ----------------- @@ -917,7 +902,7 @@ type oneTimeJob struct { // lastRun: 8 => [idx=3,found=found] => next is none // lastRun: 9 => [idx=3,found=found] => next is none func (o oneTimeJob) next(lastRun time.Time) time.Time { - idx, found := slices.BinarySearchFunc(o.sortedTimes, lastRun, timeCmp()) + idx, found := slices.BinarySearchFunc(o.sortedTimes, lastRun, ascendingTime) // if found, the next run is the following index if found { idx++ diff --git a/scheduler.go b/scheduler.go index ff816a8e..33ef385e 100644 --- a/scheduler.go +++ b/scheduler.go @@ -311,9 +311,7 @@ func (s *scheduler) selectExecJobsOutForRescheduling(id uuid.UUID) { // 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 // the subsequent next run time. - slices.SortStableFunc(j.nextScheduled, func(a, b time.Time) int { - return a.Compare(b) - }) + slices.SortStableFunc(j.nextScheduled, ascendingTime) scheduleFrom = j.nextScheduled[len(j.nextScheduled)-1] } diff --git a/scheduler_test.go b/scheduler_test.go index 78044680..58fa6546 100644 --- a/scheduler_test.go +++ b/scheduler_test.go @@ -2190,8 +2190,8 @@ func TestScheduler_AtTimesJob(t *testing.T) { }, }, { - name: "two runs in the future", - atTimes: []time.Time{n.Add(1 * time.Millisecond), n.Add(3 * time.Millisecond)}, + name: "two runs in the future - order is maintained even if times are provided out of order", + atTimes: []time.Time{n.Add(3 * time.Millisecond), n.Add(1 * time.Millisecond)}, fakeClock: clockwork.NewFakeClockAt(n), advanceAndAsserts: []func(t *testing.T, j Job, clock clockwork.FakeClock, runs *atomic.Uint32){ func(t *testing.T, j Job, clock clockwork.FakeClock, runs *atomic.Uint32) { diff --git a/util.go b/util.go index 18986b36..a4e5b6fd 100644 --- a/util.go +++ b/util.go @@ -88,12 +88,14 @@ func convertAtTimesToDateTime(atTimes AtTimes, location *time.Location) ([]time. } atTimesDate = append(atTimesDate, at.time(location)) } - slices.SortStableFunc(atTimesDate, func(a, b time.Time) int { - return a.Compare(b) - }) + slices.SortStableFunc(atTimesDate, ascendingTime) return atTimesDate, nil } +func ascendingTime(a, b time.Time) int { + return a.Compare(b) +} + type waitGroupWithMutex struct { wg sync.WaitGroup mu sync.Mutex