Skip to content

Commit

Permalink
chore: address slack feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockopp committed Jun 27, 2023
1 parent d002463 commit cc3b18c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 45 deletions.
65 changes: 26 additions & 39 deletions cmd/vela-server/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

const baseErr = "unable to schedule build"

func processSchedules(compiler compiler.Engine, database database.Interface, metadata *types.Metadata, queue queue.Service, scm scm.Service) error {
func processSchedules(base time.Duration, compiler compiler.Engine, database database.Interface, metadata *types.Metadata, queue queue.Service, scm scm.Service) error {
logrus.Infof("processing active schedules to create builds")

// send API call to capture the list of active schedules
Expand All @@ -37,23 +37,6 @@ func processSchedules(compiler compiler.Engine, database database.Interface, met

// iterate through the list of active schedules
for _, s := range schedules {
gron := gronx.New()

// check if the schedule is due based off the entry accounting for UTC
due, err := gron.IsDue(s.GetEntry(), time.Now().UTC())
if err != nil {
logrus.WithError(err).Warnf("%s for %s", baseErr, s.GetName())

continue
}

// check if the schedule is due to trigger a build
if !due {
logrus.Tracef("waiting to schedule build for %s", s.GetName())

continue
}

// send API call to capture the schedule
//
// This is needed to ensure we are not dealing with a stale schedule since we fetch
Expand All @@ -73,33 +56,37 @@ func processSchedules(compiler compiler.Engine, database database.Interface, met
continue
}

// check if a build has already been triggered for the schedule
if schedule.GetScheduledAt() > 0 {
// parse the previous occurrence of the entry for the schedule
prevTime, err := gronx.PrevTick(schedule.GetEntry(), true)
if err != nil {
logrus.WithError(err).Warnf("%s for %s", baseErr, schedule.GetName())
// capture the previous occurrence of the entry for the schedule rounded to the nearest whole interval
//
// i.e. if it's 4:02 on five minute intervals, this will be 4:00
prevTime, err := gronx.PrevTick(schedule.GetEntry(), true)
if err != nil {
logrus.WithError(err).Warnf("%s for %s", baseErr, s.GetName())

continue
}
continue
}

// parse the next occurrence of the entry for the schedule
nextTime, err := gronx.NextTick(schedule.GetEntry(), true)
if err != nil {
logrus.WithError(err).Warnf("%s for %s", baseErr, schedule.GetName())
// capture the next occurrence of the entry for the schedule rounded to the nearest whole interval
//
// i.e. if it's 4:02 on five minute intervals, this will be 4:05
nextTime, err := gronx.NextTick(schedule.GetEntry(), true)
if err != nil {
logrus.WithError(err).Warnf("%s for %s", baseErr, s.GetName())

continue
}
continue
}

// parse the UNIX timestamp from when the last build was triggered for the schedule
t := time.Unix(schedule.GetScheduledAt(), 0).UTC()
// determine if schedule is due for processing
//
// The current time must be past the next occurrence and the current time (minus sweep gap) must be
// after the previous occurrence to ensure the schedule will run at the correct time.
due := time.Now().After(nextTime) && prevTime.After(time.Now().Add(-base))

// check if the time since the last triggered build is less than the entry duration for the schedule
if time.Since(t) < nextTime.Sub(prevTime) {
logrus.Tracef("waiting to schedule build for %s", s.GetName())
// check if the schedule is due to trigger a build
if !due {
logrus.Tracef("waiting to schedule build for %s", s.GetName())

continue
}
continue
}

// process the schedule and trigger a new build
Expand Down
13 changes: 7 additions & 6 deletions cmd/vela-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,18 @@ func server(c *cli.Context) error {
// setup in the database. Since the schedule interval is configurable, we use that
// as the base duration to determine how long to sleep for.
base := c.Duration("schedule-interval")
logrus.Infof("sleeping for %v before scheduling builds", base)

// sleep for a duration of time before processing schedules
//
// This should prevent multiple servers from processing schedules at the same time by
// leveraging a base duration along with a standard deviation of randomness a.k.a.
// "jitter". To create the jitter, we use the configured minimum frequency duration
// "jitter". To create the jitter, we use the configured schedule interval duration
// along with a scale factor of 0.5.
time.Sleep(wait.Jitter(base, 0.5))
jitter := wait.Jitter(base, 0.5)

logrus.Infof("sleeping for %v before scheduling builds", jitter)
// sleep for a duration of time before processing schedules
time.Sleep(jitter)

err = processSchedules(compiler, database, metadata, queue, scm)
err = processSchedules(base, compiler, database, metadata, queue, scm)
if err != nil {
logrus.WithError(err).Warn("unable to process schedules")
} else {
Expand Down

0 comments on commit cc3b18c

Please sign in to comment.