-
Notifications
You must be signed in to change notification settings - Fork 116
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
implement @start job #52
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,11 +100,18 @@ func ParseCrontab(reader io.Reader) (*Crontab, error) { | |
continue | ||
} | ||
|
||
jobLine, err := parseJobLine(line) | ||
// replace start with so the line will parse without errors | ||
jobLine, err := parseJobLine(strings.Replace(line, StartExpressionValue, "0 0 0 1 1 * *", 1)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason to call parseJobLine if we're not really trying to parse a cron expression here? If the job line starts with |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// set custom expression for startup job | ||
if strings.HasPrefix(line, StartExpressionValue) { | ||
jobLine.Expression = StartExpr | ||
jobLine.Schedule = StartExpressionValue | ||
} | ||
|
||
jobs = append(jobs, &Job{CrontabLine: *jobLine, Position: position}) | ||
position++ | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package crontab | ||
|
||
import "time" | ||
|
||
const StartExpressionValue = "@start" | ||
|
||
var StartExpr = &StartExpression{} | ||
|
||
type StartExpression struct{} | ||
|
||
func (se StartExpression) Next(fromTime time.Time) time.Time { | ||
return time.Date(9999, 12, 31, 23, 59, 59, 0, time.Local) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,6 +104,8 @@ func main() { | |
}() | ||
} | ||
|
||
firstRun := true | ||
|
||
for true { | ||
promMetrics.Reset() | ||
|
||
|
@@ -118,20 +120,41 @@ func main() { | |
if *test { | ||
logrus.Info("crontab is valid") | ||
os.Exit(0) | ||
break | ||
} | ||
|
||
var wg sync.WaitGroup | ||
exitCtx, notifyExit := context.WithCancel(context.Background()) | ||
|
||
for _, job := range tab.Jobs { | ||
cronLogger := logrus.WithFields(logrus.Fields{ | ||
"job.schedule": job.Schedule, | ||
"job.command": job.Command, | ||
"job.position": job.Position, | ||
}) | ||
if firstRun { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather keep the code a little simpler and re-run the start jobs if you reload the crontab. There are 2 reasons for this:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, I think restarting the cron jobs when container restarts is very reasonable. Could we get this into the main code? I really would like to use it and keep using the mainline code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think it is not a good idea to run all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unlike the other review comments, it seems this needs a decision, on two points:
|
||
logrus.Info("running start jobs") | ||
for _, job := range tab.Jobs { | ||
if job.Schedule == crontab.StartExpressionValue { | ||
cronLogger := logrus.WithFields(logrus.Fields{ | ||
"job.schedule": job.Schedule, | ||
"job.command": job.Command, | ||
"job.position": job.Position, | ||
}) | ||
|
||
cron.StartJob(&wg, tab.Context, job, exitCtx, cronLogger, *overlapping, &promMetrics) | ||
} | ||
} | ||
|
||
firstRun = false | ||
wg.Wait() | ||
|
||
cron.StartJob(&wg, tab.Context, job, exitCtx, cronLogger, *overlapping, &promMetrics) | ||
logrus.Info("start jobs finished") | ||
} | ||
|
||
for _, job := range tab.Jobs { | ||
if job.Schedule != crontab.StartExpressionValue { | ||
cronLogger := logrus.WithFields(logrus.Fields{ | ||
"job.schedule": job.Schedule, | ||
"job.command": job.Command, | ||
"job.position": job.Position, | ||
}) | ||
|
||
cron.StartJob(&wg, tab.Context, job, exitCtx, cronLogger, *overlapping, &promMetrics) | ||
} | ||
} | ||
|
||
termChan := make(chan os.Signal, 1) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather handle this purely within the expression interface. Right now, this feels a little hacky, and as a result it means start jobs will not get to finish if you CTRL+C (
jobWg.Wait()
won't wait for anything andwg.Done()
will be called immediately). We also, get incomplete logging.To do this cleanly, I think we need 2 changes to the interface for
expression.Next()
:cronIteration
already).