(reader metrix.Reader)
| 117 | } |
| 118 | |
| 119 | func (e *Engine) preparePlan(reader metrix.Reader) (Plan, materializedState, uint64, uint64, uint64, bool, error) { |
| 120 | if e == nil { |
| 121 | return Plan{}, materializedState{}, 0, 0, 0, false, fmt.Errorf("chartengine: nil engine") |
| 122 | } |
| 123 | if reader == nil { |
| 124 | return Plan{}, materializedState{}, 0, 0, 0, false, fmt.Errorf("chartengine: nil metrics reader") |
| 125 | } |
| 126 | sample := planRuntimeSample{startedAt: time.Now()} |
| 127 | defer func() { e.observeBuildSample(sample) }() |
| 128 | |
| 129 | out := Plan{ |
| 130 | Actions: make([]EngineAction, 0), |
| 131 | InferredDimensions: make([]InferredDimension, 0), |
| 132 | } |
| 133 | collectMeta := reader.CollectMeta() |
| 134 | |
| 135 | e.mu.Lock() |
| 136 | defer e.mu.Unlock() |
| 137 | if e.state.outstanding != 0 { |
| 138 | return Plan{}, materializedState{}, 0, 0, 0, false, ErrOutstandingPlanAttempt |
| 139 | } |
| 140 | // Failed attempt must not trigger lifecycle transitions. |
| 141 | if collectMeta.LastAttemptStatus != metrix.CollectStatusSuccess { |
| 142 | sample.skippedFailed = true |
| 143 | e.logDebugf("chartengine build skipped: collect status=%d", collectMeta.LastAttemptStatus) |
| 144 | return out, materializedState{}, 0, 0, 0, false, nil |
| 145 | } |
| 146 | |
| 147 | obs := e.observeBuildSuccessSeq(collectMeta.LastSuccessSeq) |
| 148 | buildCycle := e.nextBuildCycle(collectMeta.LastSuccessSeq) |
| 149 | sample.buildSeqViolation = e.state.buildSeq.violating |
| 150 | sample.buildSeqObserved = true |
| 151 | switch obs.transition { |
| 152 | case buildSeqTransitionBroken: |
| 153 | sample.buildSeqBroken = true |
| 154 | e.logWarningf( |
| 155 | "chartengine build sequence is non-monotonic: current=%d previous=%d (suppressing repeats until recovery)", |
| 156 | collectMeta.LastSuccessSeq, |
| 157 | obs.previous, |
| 158 | ) |
| 159 | case buildSeqTransitionRecovered: |
| 160 | sample.buildSeqRecovered = true |
| 161 | e.logInfof( |
| 162 | "chartengine build sequence monotonicity recovered: current=%d previous=%d", |
| 163 | collectMeta.LastSuccessSeq, |
| 164 | obs.previous, |
| 165 | ) |
| 166 | } |
| 167 | |
| 168 | phaseStartedAt := time.Now() |
| 169 | staged := e.state.materialized.clone() |
| 170 | ctx, err := e.preparePlanBuildContext(reader, &out, collectMeta, buildCycle, &staged) |
| 171 | sample.phasePrepareSeconds = time.Since(phaseStartedAt).Seconds() |
| 172 | if err != nil { |
| 173 | sample.buildErr = true |
| 174 | e.logWarningf("chartengine build prepare failed: %v", err) |
| 175 | return Plan{}, materializedState{}, 0, 0, 0, false, err |
| 176 | } |
no test coverage detected