-
Notifications
You must be signed in to change notification settings - Fork 10
rollout: Roll forward only if enough time passed #57
Conversation
// TODO (gvso): Refactor this and other methods to return only a traffic object. | ||
// Then, rename this to trafficBasedOnDiagnosis. | ||
// Also, move those traffic-config-related methods to traffic.go file. |
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.
Instead of updating the service in PrepareRollForward
and PrepareRollForward
, which are deep in the call chain, we can just return the traffic config and make the update in, yeah, UpdateService
.
We need to change the first two method's name and move them (an their helpers) to a new file since this one is getting very big.
Any thoughts?
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 think the TODO above is a good idea. Though I'm fine with it as it is right now.
pkg/rollout/rollout.go
Outdated
StableRevisionAnnotation = "rollout.cloud.run/stableRevision" | ||
CandidateRevisionAnnotation = "rollout.cloud.run/candidateRevision" | ||
LastFailedCandidateRevisionAnnotation = "rollout.cloud.run/lastFailedCandidateRevision" | ||
LastRollForwardAnnotation = "rollout.cloud.run/lastRollForward" |
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.
lastRollout
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.
Done!
if err != nil { | ||
return nil, errors.Wrap(err, "failed to update service after diagnosis") | ||
} | ||
if svc == nil { |
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.
add a comment inside this if
about when this happens
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.
Done!
pkg/rollout/rollout.go
Outdated
if r.shouldRollback { | ||
svc.Metadata.Annotations[LastFailedCandidateRevisionAnnotation] = candidate | ||
delete(svc.Metadata.Annotations, LastRollForwardAnnotation) |
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 keep it (for the records)
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.
Done!
pkg/rollout/rollout.go
Outdated
return svc | ||
} | ||
|
||
svc.Metadata.Annotations[StableRevisionAnnotation] = stable | ||
svc.Metadata.Annotations[CandidateRevisionAnnotation] = candidate | ||
svc.Metadata.Annotations[LastRollForwardAnnotation] = r.time.Now().Format(time.RFC3339) |
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.
init once now := r.time.Now().Format(time.RFC3339)
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.
Done!
pkg/rollout/rollout.go
Outdated
// shouldRollForward determines if enough time has passed since last roll | ||
// forward. | ||
func (r *Rollout) shouldRollForward(lastRollForwardStr string, timeBetweenRollForwards int) (bool, error) { | ||
lastRollForward, err := time.Parse(time.RFC3339, lastRollForwardStr) |
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.
if annotation is empty, return a different error saying X annotation is missing
need to think about the case where it bricks here forever.
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 added a TODO for this
pkg/rollout/rollout.go
Outdated
@@ -318,6 +364,23 @@ func (r *Rollout) diagnoseCandidate(candidate string, healthCriteria []config.Me | |||
return d, errors.Wrap(err, "failed to diagnose candidate's health") | |||
} | |||
|
|||
// shouldRollForward determines if enough time has passed since last roll | |||
// forward. | |||
func (r *Rollout) shouldRollForward(lastRollForwardStr string, timeBetweenRollForwards int) (bool, error) { |
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.
shouldRollForward
→ isTimeElapsed
roll forward → rollout
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 renamed it to hasEnoughTimeElapsed
. Is it fine?
pkg/rollout/rollout.go
Outdated
r.log.Debugf("last roll forward: %v", lastRollForward) | ||
r.log.Debugf("current time: %v", currentTime) |
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.
these are fields
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.
lets move the log to the call site
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.
Done!
pkg/rollout/rollout_test.go
Outdated
annotations: map[string]string{ | ||
rollout.LastRollForwardAnnotation: clockMock.Now().Format(time.RFC3339), | ||
}, |
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.
create inline function
mkAnnotations := func(t time.Time, offset Duration) map[string]string {
}
inside the test function
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.
Since it can be also used in combination with other annotations, I created a utility function to generate the value instead.
pkg/rollout/rollout.go
Outdated
return svc | ||
} | ||
|
||
svc.Metadata.Annotations[StableRevisionAnnotation] = stable | ||
svc.Metadata.Annotations[CandidateRevisionAnnotation] = candidate | ||
svc.Metadata.Annotations[LastRolloutAnnotation] = now |
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.
it seems like you always do this (in both cases). so why not just set it outside the if
(e.g. right after now:=...
?
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.
Done!
This adds a new annotation containing the last time the traffic to the candidate was increased. Using the configuration for minimum time between roll forwards, it decides if it can continue rolling the candidate forward. Signed-off-by: Getulio Valentin Sánchez <gvso@google.com>
Signed-off-by: Getulio Valentin Sánchez <gvso@google.com>
Signed-off-by: Getulio Valentin Sánchez <gvso@google.com>
Signed-off-by: Getulio Valentin Sánchez <gvso@google.com>
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.
LGTM. @grayside if you want to take a look as well.
Don't have time today, and this looks good at a glance :) |
This adds a new annotation containing the last time the traffic to the candidate was increased. Using the configuration for minimum time between roll forwards, it decides if it can continue rolling the candidate forward.