Skip to content

Commit

Permalink
special case for year ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
dnr committed Sep 12, 2022
1 parent e8ca636 commit 27f2873
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 16 deletions.
16 changes: 13 additions & 3 deletions service/worker/scheduler/calendar.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const (
const (
// Modes for parsing range strings: all modes accept decimal integers
parseModeInt parseMode = iota
// parseModeYear is like parseModeInt but returns an empty range for the default
parseModeYear
// parseModeMonth also accepts month name prefixes (at least three letters)
parseModeMonth
// parseModeDow also accepts day-of-week prefixes (at least two letters)
Expand Down Expand Up @@ -100,7 +102,7 @@ var (
func newCompiledCalendar(cal *schedpb.StructuredCalendarSpec, tz *time.Location) (*compiledCalendar, error) {
cc := &compiledCalendar{tz: tz}
var err error
if cc.year, err = makeSliceMatcher(cal.Year); err != nil {
if cc.year, err = makeYearMatcher(cal.Year); err != nil {
return nil, err
} else if cc.month, err = makeBitMatcher(cal.Month); err != nil {
return nil, err
Expand Down Expand Up @@ -242,7 +244,7 @@ Outer:
func parseCalendarToStrucured(cal *schedpb.CalendarSpec) (*schedpb.StructuredCalendarSpec, error) {
ss := &schedpb.StructuredCalendarSpec{Comment: cal.Comment}
var err error
if ss.Year, err = makeRange(cal.Year, "*", minCalendarYear, maxCalendarYear, parseModeInt); err != nil {
if ss.Year, err = makeRange(cal.Year, "*", 0, 1e6, parseModeYear); err != nil {
return nil, err
} else if ss.Month, err = makeRange(cal.Month, "*", 1, 12, parseModeMonth); err != nil {
return nil, err
Expand Down Expand Up @@ -358,7 +360,12 @@ func makeBitMatcher(ranges []*schedpb.Range) (func(int) bool, error) {
return func(v int) bool { return (1<<v)&bits != 0 }, nil
}

func makeSliceMatcher(ranges []*schedpb.Range) (func(int) bool, error) {
func makeYearMatcher(ranges []*schedpb.Range) (func(int) bool, error) {
if len(ranges) == 0 {
// special case for year: all is represented as empty range list
return func(int) bool { return true }, nil
}

var values []int16
add := func(i int) { values = append(values, int16(i)) }
iterateRanges(ranges, add)
Expand Down Expand Up @@ -411,6 +418,9 @@ func makeRange(s, def string, min, max int, parseMode parseMode) ([]*schedpb.Ran
if s == "" {
s = def
}
if s == "*" && parseMode == parseModeYear {
return nil, nil // special case for year: all is represented as empty range list
}
var ranges []*schedpb.Range
for _, part := range strings.Split(s, ",") {
var err error
Expand Down
21 changes: 9 additions & 12 deletions service/worker/scheduler/calendar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,19 @@ func (s *calendarSuite) TestCalendarMatch() {
cc = s.mustCompileCalendarSpec(&schedpb.CalendarSpec{
DayOfWeek: dow,
}, time.UTC)
s.True(cc.matches(time.Date(2022, time.March, 6, 0, 0, 0, 0, time.UTC)))
s.True(cc.matches(time.Date(2022, time.March, 6, 0, 0, 0, 0, time.UTC)), dow) // sunday
}
for _, dow := range []string{"*", "5-7", "5-7/2", "6-7", "2/4", "2-7/4"} {
for _, dow := range []string{"*", "5-7", "6-7", "2/4", "2-7/4"} {
cc = s.mustCompileCalendarSpec(&schedpb.CalendarSpec{
DayOfWeek: dow,
}, time.UTC)
s.True(cc.matches(time.Date(2022, time.March, 5, 0, 0, 0, 0, time.UTC)))
s.True(cc.matches(time.Date(2022, time.March, 5, 0, 0, 0, 0, time.UTC)), dow) // saturday
}
for _, dow := range []string{"0", "7", "sun", "5-7", "5-7/2", "6-7", "2-7/5", "0-7/7", "0/7"} {
cc = s.mustCompileCalendarSpec(&schedpb.CalendarSpec{
DayOfWeek: dow,
}, time.UTC)
s.False(cc.matches(time.Date(2022, time.March, 7, 0, 0, 0, 0, time.UTC)))
s.False(cc.matches(time.Date(2022, time.March, 7, 0, 0, 0, 0, time.UTC)), dow) // monday
}
}

Expand All @@ -133,8 +133,7 @@ func (s *calendarSuite) TestParseCronString() {
Hour: []*schedpb.Range{{Start: 0, End: 23, Step: 2}},
DayOfMonth: []*schedpb.Range{{Start: 1, End: 31}},
Month: []*schedpb.Range{{Start: 1, End: 12}},
DayOfWeek: []*schedpb.Range{{Start: 0, End: 7}},
Year: []*schedpb.Range{{Start: minCalendarYear, End: maxCalendarYear}},
DayOfWeek: []*schedpb.Range{{Start: 0, End: 6}},
}, scs)
s.Nil(iv)
s.Equal("", tz)
Expand All @@ -148,7 +147,6 @@ func (s *calendarSuite) TestParseCronString() {
DayOfMonth: []*schedpb.Range{{Start: 2, End: 31, Step: 2}},
Month: []*schedpb.Range{{Start: 1, End: 12}},
DayOfWeek: []*schedpb.Range{{Start: 3, End: 4}},
Year: []*schedpb.Range{{Start: minCalendarYear, End: maxCalendarYear}},
Comment: "explanation",
}, scs)
s.Nil(iv)
Expand All @@ -162,8 +160,7 @@ func (s *calendarSuite) TestParseCronString() {
Hour: []*schedpb.Range{{Start: 0}},
DayOfMonth: []*schedpb.Range{{Start: 1}},
Month: []*schedpb.Range{{Start: 1, End: 12}},
DayOfWeek: []*schedpb.Range{{Start: 0, End: 7}},
Year: []*schedpb.Range{{Start: minCalendarYear, End: maxCalendarYear}},
DayOfWeek: []*schedpb.Range{{Start: 0, End: 6}},
}, scs)
s.Nil(iv)
s.Equal("", tz)
Expand Down Expand Up @@ -298,7 +295,7 @@ func (s *calendarSuite) TestMakeMatcher() {
if max < 63 {
m, err = makeBitMatcher(ranges)
} else {
m, err = makeSliceMatcher(ranges)
m, err = makeYearMatcher(ranges)
}
s.NoError(err)
for _, e := range expected {
Expand All @@ -313,8 +310,8 @@ func (s *calendarSuite) TestMakeMatcher() {
check("1,3,5-7", 0, 10, parseModeInt, 1, -2, 3, -4, 5, 6, 7, -8, -9, -10)
check("2-4,8,1-5/2", 1, 15, parseModeInt, 1, 2, 3, 4, 5, -6, -7, 8, -9, -10, -11, -12, -13, -14, -15)
check("February/5", 1, 12, parseModeMonth, -1, 2, -3, -4, -5, -6, 7, -8, -9, -10, -11, 12)
check("*", 0, 7, parseModeDow, 0, 1, 2, 3, 4, 5, 6, 7)
check("0", 0, 7, parseModeDow, 0, -1, -2, -3, -4, -5, -6, -7)
check("*", 0, 7, parseModeDow, 0, 1, 2, 3, 4, 5, 6)
check("0", 0, 7, parseModeDow, 0, -1, -2, -3, -4, -5, -6)
check("6,7", 0, 7, parseModeDow, 0, -1, -2, -3, -4, -5, 6) // 7 means sunday (0)
check("2020-2022,2024,2026/3", 2000, 2100, parseModeInt, -2019, 2020, 2021, 2022, -2023, 2024, -2025, 2026, -2027, -2028, 2029, -2030, 2032, 2098, -2101)
}
Expand Down
1 change: 0 additions & 1 deletion service/worker/scheduler/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ func (s *specSuite) TestCanonicalize() {
DayOfMonth: []*schedpb.Range{{Start: 1, End: 31}},
Month: []*schedpb.Range{{Start: 1, End: 12}},
DayOfWeek: []*schedpb.Range{{Start: 0, End: 6}},
Year: []*schedpb.Range{{Start: minCalendarYear, End: maxCalendarYear}},
}}
s.Equal(&schedpb.ScheduleSpec{
StructuredCalendar: structured,
Expand Down

0 comments on commit 27f2873

Please sign in to comment.