Skip to content

Commit

Permalink
allow enforcing uniqueness across tags (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnRoesler committed Mar 6, 2021
1 parent c6d876c commit b70ec13
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 32 deletions.
12 changes: 12 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,18 @@ func ExampleScheduler_Tag() {
// [tag]
}

func ExampleScheduler_TagsUnique() {
s := gocron.NewScheduler(time.UTC)
s.TagsUnique()

_, _ = s.Every(1).Week().Tag("foo").Do(task)
_, err := s.Every(1).Week().Tag("foo").Do(task)

fmt.Println(err)
// Output:
// a non-unique tag was set on the job: foo
}

func ExampleScheduler_TaskPresent() {
s := gocron.NewScheduler(time.UTC)

Expand Down
6 changes: 3 additions & 3 deletions gocron.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ var (
ErrInvalidInterval = errors.New(".Every() interval must be greater than 0")
ErrInvalidIntervalType = errors.New(".Every() interval must be int, time.Duration, or string")
ErrInvalidIntervalUnitsSelection = errors.New("an .Every() duration interval cannot be used with units (e.g. .Seconds())")

ErrAtTimeNotSupported = errors.New("the At() not supported for time unit")
ErrWeekdayNotSupported = errors.New("weekday is not supported for time unit")
ErrAtTimeNotSupported = errors.New("the At() not supported for time unit")
ErrWeekdayNotSupported = errors.New("weekday is not supported for time unit")
ErrTagsUnique = func(tag string) error { return fmt.Errorf("a non-unique tag was set on the job: %s", tag) }
)

func wrapOrError(toWrap error, err error) error {
Expand Down
21 changes: 21 additions & 0 deletions scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type Scheduler struct {

time timeWrapper // wrapper around time.Time
executor *executor // executes jobs passed via chan

tags map[string]struct{} // for storing tags when unique tags is set
}

// NewScheduler creates a new Scheduler
Expand Down Expand Up @@ -564,6 +566,17 @@ func (s *Scheduler) At(t string) *Scheduler {
// Tag will add a tag when creating a job.
func (s *Scheduler) Tag(t ...string) *Scheduler {
job := s.getCurrentJob()

if s.tags != nil {
for _, tag := range t {
if _, ok := s.tags[tag]; ok {
job.err = wrapOrError(job.err, ErrTagsUnique(tag))
return s
}
s.tags[tag] = struct{}{}
}
}

job.tags = t
return s
}
Expand Down Expand Up @@ -713,3 +726,11 @@ func (s *Scheduler) getCurrentJob() *Job {
func (s *Scheduler) now() time.Time {
return s.time.Now(s.Location())
}

// TagsUnique forces job tags to be unique across the scheduler
// when adding tags with (s *Scheduler) Tag().
// This does not enforce uniqueness on tags added via
// (j *Job) Tag()
func (s *Scheduler) TagsUnique() {
s.tags = make(map[string]struct{})
}
56 changes: 27 additions & 29 deletions scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -783,35 +783,6 @@ func TestRunJobsWithLimit(t *testing.T) {
assert.Equal(t, 1, counter)
})

// this test isn't designed well and the functionality isn't working
//t.Run("change limit", func(t *testing.T) {
// semaphore := make(chan bool)
//
// s := NewScheduler(time.UTC)
//
// j, err := s.Every(1).Second().Do(func() {
// semaphore <- true
// })
// require.NoError(t, err)
// j.LimitRunsTo(1)
//
// s.StartAsync()
// time.Sleep(1 * time.Second)
//
// j.LimitRunsTo(2)
// time.Sleep(1 * time.Second)
//
// var counter int
// select {
// case <-time.After(2 * time.Second):
// assert.Equal(t, 2, counter)
// // test passed
// case <-semaphore:
// counter++
// require.LessOrEqual(t, counter, 2)
// }
//})

t.Run("remove after last run", func(t *testing.T) {
semaphore := make(chan bool)

Expand Down Expand Up @@ -1087,3 +1058,30 @@ func TestScheduler_RemoveAfterLastRun(t *testing.T) {
}
})
}

func TestScheduler_TagsUnique(t *testing.T) {
const (
foo = "foo"
bar = "bar"
baz = "baz"
)

s := NewScheduler(time.UTC)
s.TagsUnique()

j, err := s.Every("1s").Tag(foo, bar).Do(func() {})
require.NoError(t, err)

// uniqueness not enforced on jobs tagged with job.Tag()
// thus tagging the job here is allowed
j.Tag(baz)
_, err = s.Every("1s").Tag(baz).Do(func() {})
require.NoError(t, err)

_, err = s.Every("1s").Tag(foo).Do(func() {})
assert.EqualError(t, err, ErrTagsUnique(foo).Error())

_, err = s.Every("1s").Tag(bar).Do(func() {})
assert.EqualError(t, err, ErrTagsUnique(bar).Error())

}

0 comments on commit b70ec13

Please sign in to comment.