Merge branch 'v2' into feature/scheduler-monitor

This commit is contained in:
John Roesler 2025-12-02 10:21:15 -06:00 committed by GitHub
commit c753d9989f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 88 additions and 8 deletions

View File

@ -39,7 +39,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: verify example_test.go
run: |
grep "^func [a-z-A-Z]" example_test.go | sort -c

View File

@ -18,13 +18,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
- name: golangci-lint
uses: golangci/golangci-lint-action@v9.0.0
uses: golangci/golangci-lint-action@v9.1.0
with:
version: v2.4.0
- name: test

6
job.go
View File

@ -1022,16 +1022,14 @@ type weeklyJob struct {
}
func (w weeklyJob) next(lastRun time.Time) time.Time {
firstPass := true
next := w.nextWeekDayAtTime(lastRun, firstPass)
next := w.nextWeekDayAtTime(lastRun, true)
if !next.IsZero() {
return next
}
firstPass = false
startOfTheNextIntervalWeek := (lastRun.Day() - int(lastRun.Weekday())) + int(w.interval*7)
from := time.Date(lastRun.Year(), lastRun.Month(), startOfTheNextIntervalWeek, 0, 0, 0, 0, lastRun.Location())
return w.nextWeekDayAtTime(from, firstPass)
return w.nextWeekDayAtTime(from, false)
}
func (w weeklyJob) nextWeekDayAtTime(lastRun time.Time, firstPass bool) time.Time {

View File

@ -519,6 +519,12 @@ func (s *scheduler) selectNewJob(in newJobIn) {
next = j.next(s.now())
}
if next.Before(s.now()) {
for next.Before(s.now()) {
next = j.next(next)
}
}
id := j.id
j.timer = s.exec.clock.AfterFunc(next.Sub(s.now()), func() {
select {
@ -574,6 +580,11 @@ func (s *scheduler) selectStart() {
if next.IsZero() {
next = j.next(s.now())
}
if next.Before(s.now()) {
for next.Before(s.now()) {
next = j.next(next)
}
}
jobID := id
j.timer = s.exec.clock.AfterFunc(next.Sub(s.now()), func() {
@ -831,6 +842,11 @@ func (s *scheduler) RemoveJob(id uuid.UUID) error {
}
func (s *scheduler) Start() {
if s.started.Load() {
s.logger.Warn("gocron: scheduler already started")
return
}
select {
case <-s.shutdownCtx.Done():
// Scheduler already shut down, don't notify

View File

@ -578,6 +578,41 @@ func TestScheduler_Shutdown(t *testing.T) {
})
}
func TestScheduler_Start(t *testing.T) {
defer verifyNoGoroutineLeaks(t)
t.Run("calling start multiple times is a no-op", func(t *testing.T) {
s := newTestScheduler(t)
var counter int
var mu sync.Mutex
_, err := s.NewJob(
DurationJob(
100*time.Millisecond,
),
NewTask(
func() {
mu.Lock()
counter++
mu.Unlock()
},
),
)
require.NoError(t, err)
s.Start()
s.Start()
s.Start()
time.Sleep(1000 * time.Millisecond)
require.NoError(t, s.Shutdown())
assert.Contains(t, []int{9, 10}, counter)
})
}
func TestScheduler_NewJob(t *testing.T) {
defer verifyNoGoroutineLeaks(t)
tests := []struct {
@ -2876,3 +2911,34 @@ func TestScheduler_WithMonitor(t *testing.T) {
})
}
}
func TestScheduler_WithStartAtDateTimePast(t *testing.T) {
defer verifyNoGoroutineLeaks(t)
// Monday
testTime := time.Date(2024, time.January, 1, 9, 0, 0, 0, time.UTC)
fakeClock := clockwork.NewFakeClockAt(testTime)
s := newTestScheduler(t, WithClock(fakeClock))
j, err := s.NewJob(
WeeklyJob(2, NewWeekdays(time.Sunday), NewAtTimes(NewAtTime(10, 0, 0))),
NewTask(func() {}),
WithStartAt(
// The start time is in the past (Dec 30, 2023 9am) which is a Saturday
WithStartDateTimePast(testTime.Add(-time.Hour*24*2)),
),
)
require.NoError(t, err)
s.Start()
nextRun, err := j.NextRun()
require.NoError(t, err)
require.NoError(t, s.Shutdown())
// Because the start time was in the past - we expect it to schedule 2 intervals ahead, pasing the first available Sunday
// which was in the past Dec 31, 2023, so the next is Jan 7, 2024
assert.Equal(t, time.Date(2024, time.January, 7, 10, 0, 0, 0, time.UTC), nextRun)
}