diff --git a/scheduler.go b/scheduler.go index 382c55f..c57f826 100644 --- a/scheduler.go +++ b/scheduler.go @@ -824,6 +824,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(): case s.startCh <- struct{}{}: diff --git a/scheduler_test.go b/scheduler_test.go index e040576..3c71346 100644 --- a/scheduler_test.go +++ b/scheduler_test.go @@ -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 {