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

Run jobs by Tag #149

Merged
merged 1 commit into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,3 +617,19 @@ func ExampleScheduler_Weeks() {
_, _ = s.Every(1).Week().Do(task)
_, _ = s.Every(1).Weeks().Do(task)
}

func ExampleScheduler_RunByTag() {
s := gocron.NewScheduler(time.UTC)
_, _ = s.Every(1).Day().At("10:00").Do(task)
_, _ = s.Every(2).Day().Tag("tag").At("10:00").Do(task)
s.StartAsync()
s.RunByTag("tag")
}

func ExampleScheduler_RunByTagWithDelay() {
s := gocron.NewScheduler(time.UTC)
_, _ = s.Every(1).Day().Tag("tag").At("10:00").Do(task)
_, _ = s.Every(2).Day().Tag("tag").At("10:00").Do(task)
s.StartAsync()
s.RunByTagWithDelay("tag", 2*time.Second)
}
51 changes: 33 additions & 18 deletions scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,27 @@ func (s *Scheduler) RunAllWithDelay(d time.Duration) {
}
}

// Remove specific Job job by function
// RunByTag runs all the jobs containing a specific tag
// regardless of whether they are scheduled to run or not
func (s *Scheduler) RunByTag(tag string) error {
return s.RunByTagWithDelay(tag, 0)
}

// RunByTagWithDelay is same as RunByTag but introduces a delay between
// each job execution
func (s *Scheduler) RunByTagWithDelay(tag string, d time.Duration) error {
jobs, err := s.findJobsByTag(tag)
if err != nil {
return err
}
for _, job := range jobs {
s.run(job)
s.time.Sleep(d)
}
return nil
}

// Remove specific Job by function
//
// Removing a job stops that job's timer. However, if a job has already
// been started by by the job's timer before being removed, there is no way to stop
Expand All @@ -417,7 +437,7 @@ func (s *Scheduler) Remove(job interface{}) {
})
}

// RemoveByReference removes specific Job job by reference
// RemoveByReference removes specific Job by reference
func (s *Scheduler) RemoveByReference(job *Job) {
s.removeByCondition(func(someJob *Job) bool {
job.RLock()
Expand All @@ -440,32 +460,27 @@ func (s *Scheduler) removeByCondition(shouldRemove func(*Job) bool) {

// RemoveByTag will remove a job by a given tag.
func (s *Scheduler) RemoveByTag(tag string) error {
index, err := s.findJobsIndexByTag(tag)
jobs, err := s.findJobsByTag(tag)
if err != nil {
return err
}
// Remove job if job index is valid
s.jobs[index].stop()
s.setJobs(removeAtIndex(s.jobs, index))
for _, job := range jobs {
s.RemoveByReference(job)
}
return nil
}

// Find first job index by given string
func (s *Scheduler) findJobsIndexByTag(tag string) (int, error) {
for i, job := range s.Jobs() {
func (s *Scheduler) findJobsByTag(tag string) ([]*Job, error) {
jobs := []*Job{}
for _, job := range s.Jobs() {
if strings.Contains(strings.Join(job.Tags(), " "), tag) {
return i, nil
jobs = append(jobs, job)
}
}
return -1, ErrJobNotFoundWithTag
}

func removeAtIndex(jobs []*Job, i int) []*Job {
if i == len(jobs)-1 {
return jobs[:i]
if len(jobs) > 0 {
return jobs, nil
}
jobs = append(jobs[:i], jobs[i+1:]...)
return jobs
return nil, ErrJobNotFoundWithTag
}

// LimitRunsTo limits the number of executions of this job to n.
Expand Down
20 changes: 20 additions & 0 deletions scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1135,3 +1135,23 @@ func TestScheduler_Update(t *testing.T) {
assert.EqualError(t, err, ErrUpdateCalledWithoutJob.Error())
})
}

func TestScheduler_RunByTag(t *testing.T) {
var (
s = NewScheduler(time.Local)
count = 0
wg sync.WaitGroup
)

s.Every(1).Day().StartAt(time.Now().Add(time.Hour)).Tag("tag").Do(func() {
count++
wg.Done()
})
wg.Add(1)
s.StartAsync()
assert.NoError(t, s.RunByTag("tag"))

wg.Wait()
assert.Equal(t, 1, count)
assert.Error(t, s.RunByTag("wrong-tag"))
}