Skip to content

feat: add crontab package for supporting autostart/stop. #844

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

Merged
merged 9 commits into from
Apr 4, 2022
Prev Previous commit
Next Next commit
fix: doc comments
  • Loading branch information
johnstcn committed Apr 4, 2022
commit 91cc3b62b7d49a43fd48debb8a8fc9c85d0f4199
42 changes: 23 additions & 19 deletions coderd/crontab/crontab.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// package crontab provides utilities for parsing and deserializing
// cron-style expressions.
package crontab

import (
Expand All @@ -7,11 +9,13 @@ import (
"golang.org/x/xerrors"
)

// For the purposes of this library, we only need minute, hour, and
//day-of-week.
const parserFormat = cron.Minute | cron.Hour | cron.Dow

var defaultParser = cron.NewParser(parserFormat)

// CronSchedule represents a weekly cron schedule serializable to and from a string.
// Parse parses a WeeklySchedule from spec.
//
// Example Usage:
// local_sched, _ := cron.Parse("59 23 *")
Expand All @@ -20,24 +24,6 @@ var defaultParser = cron.NewParser(parserFormat)
// us_sched, _ := cron.Parse("CRON_TZ=US/Central 30 9 1-5")
// fmt.Println(sched.Next(time.Now()).Format(time.RFC3339))
// // Output: 2022-04-04T14:30:00Z

// WeeklySchedule is a thin wrapper for cron.SpecSchedule that implements Stringer.
type WeeklySchedule struct {
sched *cron.SpecSchedule
// XXX: there isn't any nice way for robfig/cron to serialize
spec string
}

// String serializes the schedule to its original human-friendly format.
func (s WeeklySchedule) String() string {
return s.spec
}

// Next returns the next time in the schedule relative to t.
func (s WeeklySchedule) Next(t time.Time) time.Time {
return s.sched.Next(t)
}

func Parse(spec string) (*WeeklySchedule, error) {
specSched, err := defaultParser.Parse(spec)
if err != nil {
Expand All @@ -55,3 +41,21 @@ func Parse(spec string) (*WeeklySchedule, error) {
}
return cronSched, nil
}

// WeeklySchedule represents a weekly cron schedule.
// It's essentially a thin wrapper for robfig/cron/v3 that implements Stringer.
type WeeklySchedule struct {
Copy link
Member

Choose a reason for hiding this comment

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

This weekly schedule feels pretty specified to autostart/stop. Could we add this to the autostart/stop package once that's in (assuming it'll be inside it's own package)?

Copy link
Member

Choose a reason for hiding this comment

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

Also, I'm not sure this needs to have Weekly as a prefix. That seems like part of the parsing logic, not the struct functionality.

Copy link
Member Author

Choose a reason for hiding this comment

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

I can move this to coderd/autostart/schedule if that works?

Copy link
Member

Choose a reason for hiding this comment

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

Based on what's here, I'd say that makes sense. I'm uncertain what structurally makes sense until we have more of the implementation worked out, but as long as we're not opposed to moving this afterwards, I'm good with it!

sched *cron.SpecSchedule
// XXX: there isn't any nice way for robfig/cron to serialize
spec string
}

// String serializes the schedule to its original human-friendly format.
func (s WeeklySchedule) String() string {
return s.spec
}

// Next returns the next time in the schedule relative to t.
func (s WeeklySchedule) Next(t time.Time) time.Time {
return s.sched.Next(t)
}