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

fix scheduler restart #825

Merged
merged 2 commits into from
Feb 7, 2025
Merged

fix scheduler restart #825

merged 2 commits into from
Feb 7, 2025

Conversation

27149chen
Copy link
Contributor

What does this do?

There is an issue introduced by #819

Steps to reproduce:

  1. use a job function starts with ctx and do not pass an ctx
  2. stop the scheduler by running .StopJobs()
  3. start the scheduler by running .Start()
  4. the job function does not work properly since ctx is already cancelled

This pr fix it by updating the ctx after job is stopped

Which issue(s) does this PR fix/relate to?

related to #819

List any changes that modify/break current functionality

Have you included tests for your changes?

yes

Did you document any new/modified functionality?

  • Updated example_test.go
  • Updated README.md

Notes

Signed-off-by: lou <alex1988@outlook.com>

// also replace the old context with the new one in the parameters
if len(j.parameters) > 0 && j.parameters[0] == oldCtx {
j.parameters[0] = j.ctx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @27149chen thanks for the PR. Right now, this causes a race condition because we haven't waited for the jobs to fully stopped. If you duplicate and move this for loop block down right above s.stopErrCh <- err then we'll have waited for the <-s.exec.done chan to report back and update the job params race free.

Here is the full stopScheduler func with that change:

func (s *scheduler) stopScheduler() {
	s.logger.Debug("gocron: stopping scheduler")
	if s.started {
		s.exec.stopCh <- struct{}{}
	}

	for _, j := range s.jobs {
		j.stop()
	}
	for _, j := range s.jobs {
		<-j.ctx.Done()
	}
	var err error
	if s.started {
		t := time.NewTimer(s.exec.stopTimeout + 1*time.Second)
		select {
		case err = <-s.exec.done:
			t.Stop()
		case <-t.C:
			err = ErrStopExecutorTimedOut
		}
	}
	for id, j := range s.jobs {
		oldCtx := j.ctx
		if j.parentCtx == nil {
			j.parentCtx = s.shutdownCtx
		}
		j.ctx, j.cancel = context.WithCancel(j.parentCtx)

		// also replace the old context with the new one in the parameters
		if len(j.parameters) > 0 && j.parameters[0] == oldCtx {
			j.parameters[0] = j.ctx
		}

		s.jobs[id] = j
	}

	s.stopErrCh <- err
	s.started = false
	s.logger.Debug("gocron: scheduler stopped")
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JohnRoesler thanks, updated

Signed-off-by: lou <alex1988@outlook.com>
@JohnRoesler JohnRoesler merged commit a757eff into go-co-op:v2 Feb 7, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants