Commit b8caaab
authored
fix(speculate): wait for every assumption to settle before merging (#559)
## Summary
### Why?
A head could merge on an assumption that had not come true.
`mergeablePath` required every dependency a path assumed would *succeed*
to have actually merged, but imposed no wait at all on one it assumed
would *fail*.
The doc comment stated the reasoning: *"A dependency assumed to fail
imposes no wait: the path is broken the moment that dependency succeeds,
so a still-live path has already been vindicated on it."* That holds
only if the transition were instantaneous. It is not — a dependency
spends time in `speculating`, and then in `merging`, having neither
succeeded nor failed. `assumptionBroken` only fires on a terminal state,
so throughout that window the path is neither broken nor vindicated. It
is unsettled, and the gate read unsettled as permission.
A path that assumed a dependency would fail was built *without* that
dependency's changes. Landing the head while that dependency is still
live, and watching it land too, puts a combination on the trunk that no
build ever validated — the one thing the queue exists to prevent. It
needs no textual conflict to break the trunk, because the two changes
were never built together.
Measured against the real predicates before fixing, with a passed
`fails(D)` path and only D's state varying:
| D's state | `mergeablePath` | correct? |
| -- | -- | -- |
| `speculating` | true | no |
| `merging` | true | no |
| `cancelling` | true | no |
| `failed` | true | yes — the assumption came true |
| `succeeded` | false | yes — `assumptionBroken` catches it |
`decide` returned `merge` in all three of the wrong rows.
### What?
The rule is now symmetric: a path may merge once every dependency has
finished the way it assumed. `succeeds` needs `Succeeded`; `fails` needs
`Failed` or `Cancelled`. `allAssumedSucceedingMerged` becomes
`allAssumptionsSettled`, since it no longer looks only at succeeding
dependencies.
One wording consequence of the parent commit dropping the *ignored*
assumption: the old doc sold this gate as "the head waits only on the
dependencies it was built on top of, not its full dependency list". With
every dependency carrying a position, that is no longer what speculation
buys. What it buys is that the build already ran — when the dependencies
land the way the path guessed there is nothing left to execute, and the
head merges at once.
Note this is not the "bypass large diff" early merge the RFC describes.
That reads a passed path for *every* combination of the dependencies,
and is not implemented on the controller side — nothing enumerates
combinations. A single path betting the right way was never a sound
approximation of it, and `speculation.md` now says so rather than
describing behaviour the code does not have.
One liveness consequence, recorded on CODEM-428 rather than fixed here:
a dependency stuck in `Cancelling` now stalls its dependents too, not
just itself. `finalizeCancellations` converges `Cancelling → Cancelled`
on any subsequent run, so this only bites when no further run is
triggered — which is that issue's edge-triggering gap.
## Test Plan
- ✅ `make test` — 96/96 pass
- ✅ `make lint`, `make check-gazelle`, `make check-tidy`
`TestMergeablePath` is rebuilt around the new rule, holding the second
dependency settled so the first is the only variable: a fails assumption
waits out `speculating`, `merging` and `cancelling`, and merges on
`Failed` or `Cancelled`; an assumed-succeeding dependency waits out its
merge; one unsettled dependency is enough to wait.
## Issue
Fixes https://linear.app/uber/issue/CODEM-4291 parent e8b69f8 commit b8caaab
3 files changed
Lines changed: 74 additions & 21 deletions
File tree
- doc/rfc/submitqueue
- submitqueue/orchestrator/controller/speculate
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
| 57 | + | |
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
| 80 | + | |
79 | 81 | | |
80 | 82 | | |
81 | 83 | | |
| |||
Lines changed: 29 additions & 18 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
64 | | - | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
65 | 66 | | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
70 | 71 | | |
71 | | - | |
72 | | - | |
73 | | - | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
74 | 79 | | |
75 | 80 | | |
76 | 81 | | |
| |||
79 | 84 | | |
80 | 85 | | |
81 | 86 | | |
82 | | - | |
| 87 | + | |
83 | 88 | | |
84 | 89 | | |
85 | 90 | | |
86 | 91 | | |
87 | 92 | | |
88 | 93 | | |
89 | | - | |
90 | | - | |
91 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
92 | 98 | | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
98 | 109 | | |
99 | 110 | | |
100 | 111 | | |
| |||
Lines changed: 42 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
| 50 | + | |
49 | 51 | | |
50 | 52 | | |
51 | 53 | | |
52 | 54 | | |
| 55 | + | |
53 | 56 | | |
54 | 57 | | |
55 | 58 | | |
56 | 59 | | |
57 | 60 | | |
58 | 61 | | |
| 62 | + | |
59 | 63 | | |
60 | 64 | | |
61 | 65 | | |
62 | | - | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
63 | 74 | | |
64 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
65 | 105 | | |
66 | 106 | | |
67 | 107 | | |
68 | | - | |
| 108 | + | |
69 | 109 | | |
70 | 110 | | |
71 | 111 | | |
| |||
0 commit comments