Commit 0573024
committed
feat: reconciler plans the start phase
The plan learns the start vocabulary — inert until a caller opts in
(ReconcileOptions.Scope, zero value keeps today's create-only plans
byte-identical):
- OpWaitCondition, one node per (awaited service, condition),
deduplicated across dependents like networkNodes deduplicates
networks; required:false marks the shared node best-effort, one
required dependent upgrades it. service_started needs no node — a
plain DAG edge to the dependency's chain end expresses it. Health is
deliberately re-observed at execution time: the plan encodes what to
wait for, never a stale observation.
- OpRunPreStart, emitted at plan time only when no replica was running
at observation — the imperative gating — targeting the
lowest-numbered replica.
- OpRunPostStart per container, after its start.
- replica chains: inject+start+post_start of replica n+1 depends on
the end of replica n's chain, today's sequential start order made
visible in golden plans; startChainEnds points at the chain end so a
service_started dependent waits for the whole service, matching
InDependencyOrder semantics.
- scope Start plans starting observed exited/created containers
without converging them (the future compose start); scope
CreateStart appends the start phase to the create plan, start nodes
resolving their target from the create node that materializes the
replica (CreateNodeID, the mechanism OpRenameContainer already
uses).
Lifecycle parity with the imperative engine is load-bearing and
golden-locked:
- dependency conditions are evaluated even when nothing has to start
(waitDependencies runs for every visited service before looking at
what to start), so an up with everything running still fails on an
unhealthy required dependency;
- an exceptional-state replica takes NO start-phase node: its bare
create-phase restart leaves it running when the start phase looks, so
the imperative engine neither re-starts nor injects — and it gates
pre_start like any running replica;
- startChainEnds carries the end-of-visit node set (waits included when
nothing started), so a service_started dependent begins only once the
dependency's whole visit completed, matching InDependencyOrder;
- under scope Start, a scale>0 service with no container at all fails
the plan with startService's exact error.
The "service:<name>:<number>" resource-ID format is built and parsed in
one place (serviceReplicaID/serviceReplicaPrefix/startGroupID), and the
replica sort deliberately carries the plan's determinism over the
unordered containerNodes iteration.
Golden tests only; no executor support yet and no caller passes the
scope. Epic #14081, Lot 1 — reconciler (first item).
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>1 parent 460cf3c commit 0573024
3 files changed
Lines changed: 932 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
56 | 73 | | |
57 | 74 | | |
58 | 75 | | |
| |||
82 | 99 | | |
83 | 100 | | |
84 | 101 | | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
85 | 108 | | |
86 | 109 | | |
87 | 110 | | |
| |||
102 | 125 | | |
103 | 126 | | |
104 | 127 | | |
105 | | - | |
| 128 | + | |
| 129 | + | |
106 | 130 | | |
107 | 131 | | |
108 | 132 | | |
| |||
118 | 142 | | |
119 | 143 | | |
120 | 144 | | |
| 145 | + | |
121 | 146 | | |
122 | 147 | | |
123 | 148 | | |
| |||
171 | 196 | | |
172 | 197 | | |
173 | 198 | | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
174 | 202 | | |
175 | 203 | | |
176 | 204 | | |
| |||
0 commit comments