Unify pre-execution stage decisions
This commit is contained in:
@@ -34,21 +34,89 @@ type priorStageOutcome struct {
|
||||
outputs int
|
||||
}
|
||||
|
||||
func decideStageAction(s stage.Stage, m *manifest.Manifest, force bool) stageAction {
|
||||
// A succeeded aggregate record is the initial skip candidate. The runner and
|
||||
// planner then let stage-owned resume validation refine that decision.
|
||||
if !force && stageSucceeded(m, s.Name()) {
|
||||
return stageActionSkip
|
||||
}
|
||||
return stageActionRun
|
||||
type preExecutionDecision struct {
|
||||
action stageAction
|
||||
markSelectedStale bool
|
||||
selectedStaleReason string
|
||||
invalidationReason string
|
||||
invalidateWhenStarted bool
|
||||
}
|
||||
|
||||
func stageSucceeded(m *manifest.Manifest, name string) bool {
|
||||
func decideStageExecution(status manifest.StageStatus, force bool, resume *stage.ResumeValidation) preExecutionDecision {
|
||||
if force {
|
||||
return preExecutionDecision{
|
||||
action: stageActionRun,
|
||||
invalidationReason: staleReasonForcedReplacement,
|
||||
invalidateWhenStarted: true,
|
||||
}
|
||||
}
|
||||
if status != manifest.StatusSucceeded {
|
||||
return preExecutionDecision{action: stageActionRun}
|
||||
}
|
||||
if resume != nil && !resume.Resumable {
|
||||
return preExecutionDecision{
|
||||
action: stageActionRun,
|
||||
markSelectedStale: true,
|
||||
selectedStaleReason: resume.Reason,
|
||||
invalidationReason: staleReasonNotResumable,
|
||||
}
|
||||
}
|
||||
return preExecutionDecision{action: stageActionSkip}
|
||||
}
|
||||
|
||||
func recordedStageStatus(m *manifest.Manifest, name string) manifest.StageStatus {
|
||||
if m == nil || m.Stages == nil {
|
||||
return false
|
||||
return ""
|
||||
}
|
||||
sr := m.Stages[name]
|
||||
return sr != nil && sr.Status == manifest.StatusSucceeded
|
||||
if sr == nil {
|
||||
return ""
|
||||
}
|
||||
return sr.Status
|
||||
}
|
||||
|
||||
func applyPreExecutionDecision(m *manifest.Manifest, name string, decision preExecutionDecision, at time.Time) ([]string, error) {
|
||||
if !decision.markSelectedStale {
|
||||
return nil, nil
|
||||
}
|
||||
m.MarkStageStale(name, at, decision.selectedStaleReason)
|
||||
return invalidateDependentSucceededStagesWithReason(m, name, at, decision.invalidationReason)
|
||||
}
|
||||
|
||||
func beginStageAttempt(m *manifest.Manifest, name string, decision preExecutionDecision, at time.Time) ([]string, error) {
|
||||
m.MarkStageRunning(name, at)
|
||||
if !decision.invalidateWhenStarted {
|
||||
return nil, nil
|
||||
}
|
||||
return invalidateDependentSucceededStagesWithReason(m, name, at, decision.invalidationReason)
|
||||
}
|
||||
|
||||
func applyCompletedStageOutcome(
|
||||
m *manifest.Manifest,
|
||||
name string,
|
||||
result *stage.StageResult,
|
||||
outputs []manifest.ArtifactRecord,
|
||||
semanticConfig *manifest.SemanticConfigFingerprint,
|
||||
prior priorStageOutcome,
|
||||
at time.Time,
|
||||
) ([]string, error) {
|
||||
if result != nil && result.Disposition == stage.StageDispositionSkipped {
|
||||
m.MarkStageSkipped(name, at, result.SkipReason)
|
||||
applyStageResultToManifest(m, name, result)
|
||||
setSessionStageSemanticConfig(m, name, semanticConfig)
|
||||
if prior.isSameSelfSkip(result.SkipReason) {
|
||||
return nil, nil
|
||||
}
|
||||
return invalidateDependentSucceededStagesWithReason(m, name, at, staleReasonSelfSkip)
|
||||
}
|
||||
|
||||
m.MarkStageSucceeded(name, at, outputs)
|
||||
applyStageResultToManifest(m, name, result)
|
||||
setSessionStageSemanticConfig(m, name, semanticConfig)
|
||||
if prior.exists && prior.status == manifest.StatusSucceeded {
|
||||
return nil, nil
|
||||
}
|
||||
return invalidateDependentSucceededStagesWithReason(m, name, at, staleReasonChangedResult)
|
||||
}
|
||||
|
||||
func capturePriorStageOutcome(m *manifest.Manifest, name string) priorStageOutcome {
|
||||
|
||||
Reference in New Issue
Block a user