Skip to content

Commit 0e62c57

Browse files
committed
timing was off - need to cancel context before returning early
1 parent b04e3b9 commit 0e62c57

File tree

2 files changed

+12
-16
lines changed

2 files changed

+12
-16
lines changed

scheduler.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"runtime"
88
"slices"
99
"strings"
10+
"sync/atomic"
1011
"time"
1112

1213
"github.com/google/uuid"
@@ -72,7 +73,7 @@ type scheduler struct {
7273
// the location used by the scheduler for scheduling when relevant
7374
location *time.Location
7475
// whether the scheduler has been started or not
75-
started bool
76+
started atomic.Bool
7677
// globally applied JobOption's set on all jobs added to the scheduler
7778
// note: individually set JobOption's take precedence.
7879
globalJobOptions []JobOption
@@ -233,13 +234,8 @@ func NewScheduler(options ...SchedulerOption) (Scheduler, error) {
233234

234235
func (s *scheduler) stopScheduler() {
235236
s.logger.Debug("gocron: stopping scheduler")
236-
if !s.started {
237-
s.logger.Debug("gocron: scheduler already stopped")
238-
s.stopErrCh <- nil
239-
return
240-
}
241237

242-
if s.started {
238+
if s.started.Load() {
243239
s.exec.stopCh <- struct{}{}
244240
}
245241

@@ -250,7 +246,7 @@ func (s *scheduler) stopScheduler() {
250246
<-j.ctx.Done()
251247
}
252248
var err error
253-
if s.started {
249+
if s.started.Load() {
254250
t := time.NewTimer(s.exec.stopTimeout + 1*time.Second)
255251
select {
256252
case err = <-s.exec.done:
@@ -275,7 +271,7 @@ func (s *scheduler) stopScheduler() {
275271
}
276272

277273
s.stopErrCh <- err
278-
s.started = false
274+
s.started.Store(false)
279275
s.logger.Debug("gocron: scheduler stopped")
280276
}
281277

@@ -480,7 +476,7 @@ func (s *scheduler) selectJobOutRequest(out *jobOutRequest) {
480476

481477
func (s *scheduler) selectNewJob(in newJobIn) {
482478
j := in.job
483-
if s.started {
479+
if s.started.Load() {
484480
next := j.startTime
485481
if j.startImmediately {
486482
next = s.now()
@@ -531,7 +527,7 @@ func (s *scheduler) selectStart() {
531527
s.logger.Debug("gocron: scheduler starting")
532528
go s.exec.start()
533529

534-
s.started = true
530+
s.started.Store(true)
535531
for id, j := range s.jobs {
536532
next := j.startTime
537533
if j.startImmediately {
@@ -826,15 +822,16 @@ func (s *scheduler) StopJobs() error {
826822
}
827823

828824
func (s *scheduler) Shutdown() error {
829-
if !s.started {
825+
s.logger.Debug("scheduler shutting down")
826+
827+
s.shutdownCancel()
828+
if !s.started.Load() {
830829
return nil
831830
}
832-
s.shutdownCancel()
833831

834832
t := time.NewTimer(s.exec.stopTimeout + 2*time.Second)
835833
select {
836834
case err := <-s.stopErrCh:
837-
838835
t.Stop()
839836
return err
840837
case <-t.C:

scheduler_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,9 @@ func TestScheduler_Shutdown(t *testing.T) {
568568
assert.ErrorIs(t, err, ErrJobNotFound)
569569
})
570570

571-
t.Run("calling shutdown multiple times including before start is a no-op", func(t *testing.T) {
571+
t.Run("calling shutdown multiple times is a no-op", func(t *testing.T) {
572572
s := newTestScheduler(t)
573573

574-
assert.NoError(t, s.Shutdown())
575574
s.Start()
576575

577576
assert.NoError(t, s.Shutdown())

0 commit comments

Comments
 (0)