Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5ad048b

Browse files
committed
feat: schedule: add schedule.Min function to determine minimum interval
1 parent 7da27a0 commit 5ad048b

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

coderd/autobuild/schedule/schedule.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,36 @@ func (s Schedule) Next(t time.Time) time.Time {
108108
return s.sched.Next(t)
109109
}
110110

111+
var t0 = time.Date(1970, 1, 1, 1, 1, 1, 0, time.UTC)
112+
var tMax = t0.Add(168 * time.Hour)
113+
114+
// Min returns the minimum duration of the schedule.
115+
// This is calculated as follows:
116+
// - Let t(0) be a given point in time (1970-01-01T01:01:01Z00:00)
117+
// - Let t(max) be 168 hours after t(0).
118+
// - Let t(1) be the next scheduled time after t(0).
119+
// - Let t(n) be the next scheduled time after t(n-1).
120+
// - Then, the minimum duration of s d(min)
121+
// = min( t(n) - t(n-1) ∀ n ∈ N, t(n) < t(max) )
122+
func (s Schedule) Min() time.Duration {
123+
durMin := tMax.Sub(t0)
124+
tPrev := s.Next(t0)
125+
tCurr := s.Next(tPrev)
126+
for {
127+
dur := tCurr.Sub(tPrev)
128+
if dur < durMin {
129+
durMin = dur
130+
}
131+
tmp := tCurr
132+
tCurr = s.Next(tmp)
133+
tPrev = tmp
134+
if tCurr.After(tMax) {
135+
break
136+
}
137+
}
138+
return durMin
139+
}
140+
111141
// validateWeeklySpec ensures that the day-of-month and month options of
112142
// spec are both set to *
113143
func validateWeeklySpec(spec string) error {

coderd/autobuild/schedule/schedule_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ func Test_Weekly(t *testing.T) {
1616
spec string
1717
at time.Time
1818
expectedNext time.Time
19+
expectedMin time.Duration
1920
expectedError string
2021
expectedCron string
2122
expectedTz string
@@ -26,6 +27,7 @@ func Test_Weekly(t *testing.T) {
2627
spec: "CRON_TZ=US/Central 30 9 * * 1-5",
2728
at: time.Date(2022, 4, 1, 14, 29, 0, 0, time.UTC),
2829
expectedNext: time.Date(2022, 4, 1, 14, 30, 0, 0, time.UTC),
30+
expectedMin: 24 * time.Hour,
2931
expectedError: "",
3032
expectedCron: "30 9 * * 1-5",
3133
expectedTz: "US/Central",
@@ -36,11 +38,34 @@ func Test_Weekly(t *testing.T) {
3638
spec: "30 9 * * 1-5",
3739
at: time.Date(2022, 4, 1, 9, 29, 0, 0, time.UTC),
3840
expectedNext: time.Date(2022, 4, 1, 9, 30, 0, 0, time.UTC),
41+
expectedMin: 24 * time.Hour,
3942
expectedError: "",
4043
expectedCron: "30 9 * * 1-5",
4144
expectedTz: "UTC",
4245
expectedString: "CRON_TZ=UTC 30 9 * * 1-5",
4346
},
47+
{
48+
name: "convoluted with timezone",
49+
spec: "CRON_TZ=US/Central */5 12-18 * * 1,3,6",
50+
at: time.Date(2022, 4, 1, 14, 29, 0, 0, time.UTC),
51+
expectedNext: time.Date(2022, 4, 2, 17, 0, 0, 0, time.UTC), // Apr 1 was a Friday in 2022
52+
expectedMin: 5 * time.Minute,
53+
expectedError: "",
54+
expectedCron: "*/5 12-18 * * 1,3,6",
55+
expectedTz: "US/Central",
56+
expectedString: "CRON_TZ=US/Central */5 12-18 * * 1,3,6",
57+
},
58+
{
59+
name: "another convoluted example",
60+
spec: "CRON_TZ=US/Central 10,20,40-50 * * * *",
61+
at: time.Date(2022, 4, 1, 14, 29, 0, 0, time.UTC),
62+
expectedNext: time.Date(2022, 4, 1, 14, 40, 0, 0, time.UTC),
63+
expectedMin: time.Minute,
64+
expectedError: "",
65+
expectedCron: "10,20,40-50 * * * *",
66+
expectedTz: "US/Central",
67+
expectedString: "CRON_TZ=US/Central 10,20,40-50 * * * *",
68+
},
4469
{
4570
name: "time.Local will bite you",
4671
spec: "CRON_TZ=Local 30 9 * * 1-5",
@@ -104,6 +129,7 @@ func Test_Weekly(t *testing.T) {
104129
require.Equal(t, testCase.expectedCron, actual.Cron())
105130
require.Equal(t, testCase.expectedTz, actual.Timezone())
106131
require.Equal(t, testCase.expectedString, actual.String())
132+
require.Equal(t, testCase.expectedMin, actual.Min())
107133
} else {
108134
require.EqualError(t, err, testCase.expectedError)
109135
require.Nil(t, actual)

0 commit comments

Comments
 (0)