Skip to content

Commit

Permalink
calling .Stop() from a separate goroutine now stops the blocking start (
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnRoesler authored Jun 29, 2022
1 parent 8de08e7 commit 9b157fc
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
12 changes: 12 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,20 @@ func ExampleScheduler_Stop() {
s.StartAsync()
s.Stop()
fmt.Println(s.IsRunning())

s = gocron.NewScheduler(time.UTC)

go func() {
time.Sleep(1 * time.Second)
s.Stop()
}()

s.StartBlocking()
fmt.Println(".Stop() stops the blocking start")

// Output:
// false
// .Stop() stops the blocking start
}

func ExampleScheduler_Sunday() {
Expand Down
2 changes: 1 addition & 1 deletion executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (e *executor) start() {

if panicHandler != nil {
defer func() {
if r := recover(); r != nil {
if r := recover(); r != interface{}(nil) {
panicHandler(f.name, r)
}
}()
Expand Down
9 changes: 7 additions & 2 deletions scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type Scheduler struct {
waitForInterval bool // defaults jobs to waiting for first interval to start
singletonMode bool // defaults all jobs to use SingletonMode()
jobCreated bool // so the scheduler knows a job was created prior to calling Every or Cron

stopChan chan struct{} // stops the scheduler
}

// days in a week
Expand All @@ -52,6 +54,7 @@ func NewScheduler(loc *time.Location) *Scheduler {
time: &trueTime{},
executor: &executor,
tagsUnique: false,
stopChan: make(chan struct{}, 1),
}
}

Expand All @@ -62,10 +65,11 @@ func (s *Scheduler) SetMaxConcurrentJobs(n int, mode limitMode) {
s.executor.limitMode = mode
}

// StartBlocking starts all jobs and blocks the current thread
// StartBlocking starts all jobs and blocks the current thread.
// This blocking method can be stopped with Stop() from a separate goroutine.
func (s *Scheduler) StartBlocking() {
s.StartAsync()
<-make(chan bool)
<-s.stopChan
}

// StartAsync starts all jobs without blocking the current thread
Expand Down Expand Up @@ -807,6 +811,7 @@ func (s *Scheduler) Stop() {
func (s *Scheduler) stop() {
s.setRunning(false)
s.executor.stop()
s.stopChan <- struct{}{}
}

func (s *Scheduler) doCommon(jobFun interface{}, params ...interface{}) (*Job, error) {
Expand Down
14 changes: 14 additions & 0 deletions scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,20 @@ func TestScheduler_Stop(t *testing.T) {

assert.EqualValues(t, 1, atomic.LoadInt32(&i))
})
t.Run("stops a running scheduler calling .Stop()", func(t *testing.T) {
s := NewScheduler(time.UTC)

go func() {
time.Sleep(1 * time.Second)
assert.True(t, s.IsRunning())
s.Stop()
time.Sleep(100 * time.Millisecond) // wait for stop goroutine to catch up
}()

s.StartBlocking()
log.Println(".Stop() stops the blocking start")
assert.False(t, s.IsRunning())
})
}

func TestScheduler_StartAt(t *testing.T) {
Expand Down

0 comments on commit 9b157fc

Please sign in to comment.