Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] - Data Race between scheduler stopping a job and stopping the scheduler #539

Closed
ryanrazsa opened this issue Aug 16, 2023 · 0 comments
Labels
bug Something isn't working

Comments

@ryanrazsa
Copy link

ryanrazsa commented Aug 16, 2023

Describe the bug

If a job is removed by the scheduler due to a condition (ex max runs is hit), and the scheduler is stopped, a data race occurs.

To Reproduce

Steps to reproduce the behavior:

  1. Schedule a job with a max number of runs
  2. Wait for the job to hit the max runs
  3. Stop the scheduler

To reproduce in test code

func TestDataRace(t *testing.T) {
	sut := gocron.NewScheduler(time.UTC)
	sut.StartAsync()
	maxRuns := 10
	task := func() {
	}

	_, err := sut.
		Every(1).
		Milliseconds().
		Tag("name").
		SingletonMode().
		LimitRunsTo(maxRuns).
		Do(task)
	assert.NoError(t, err)

	time.Sleep(1 * time.Second)
	sut.Stop()
}

go test -race ./...

=== RUN   TestDataRace
==================
WARNING: DATA RACE
Read at 0x00c000192018 by goroutine 6:
  github.com/go-co-op/gocron.(*Scheduler).stop()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:895 +0x30
  github.com/go-co-op/gocron.(*Scheduler).Stop()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:890 +0x50
  github.com/StackAdapt/go-user-writer/internal/scheduler.TestDataRace()
      scheduler_test.go:140 +0x100
  testing.tRunner()
      /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1576 +0x188
  testing.(*T).Run.func1()
      /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1629 +0x40

Previous write at 0x00c000192018 by goroutine 31:
  github.com/go-co-op/gocron.(*Scheduler).setJobs()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:147 +0x78
  github.com/go-co-op/gocron.(*Scheduler).removeByCondition()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:728 +0x18c
  github.com/go-co-op/gocron.(*Scheduler).RemoveByReference()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:692 +0x54
  github.com/go-co-op/gocron.(*Scheduler).scheduleNextRun()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:222 +0x614
  github.com/go-co-op/gocron.(*Scheduler).runContinuous()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:599 +0x34
  github.com/go-co-op/gocron.(*Scheduler).runContinuous.func1()
      github.com/go-co-op/gocron@v1.31.1/scheduler.go:632 +0x238

Version

v1.31.1
go1.20.3

Expected behavior

Possibly expecting stopJobs to use the jobsMutex

Additional context

I don't know the repo well enough to know the implications of this fix, but I created a PR as an example of how it can be fixed

#540

@ryanrazsa ryanrazsa added the bug Something isn't working label Aug 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants