Pin the resume of a lost walk's refusals beside a newer or a related plan, and cite ADR 0360 §7 and ADR 0531 (issue 1886)
mesh/merge-gate head 4d4d51eb017f merged into trunk 219fdcd7f00c — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; the ch…
mesh/repo-check head 4d4d51eb017f merged into trunk 219fdcd7f00c — pass: its merge-check.sh passed
mesh/delivery delivered
mesh/check failed: integration: github.com/novox/mesh-controller/internal/identity.TestACertificateChainsToTheMeshsOwnAuthority: authority_test.go:45:…
mesh/merge-gate head 4d4d51eb017f merged into trunk 219fdcd7f00c — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; the ch…
mesh/repo-check head 4d4d51eb017f merged into trunk 219fdcd7f00c — pass: its merge-check.sh passed
mesh/delivery delivered
mesh/check failed: integration: github.com/novox/mesh-controller/internal/identity.TestACertificateChainsToTheMeshsOwnAuthority: authority_test.go:45:…
This commit is contained in:
@@ -218,7 +218,7 @@ func retryRefusal(p inventory.Plan, plans []inventory.Plan, onPath map[string]st
|
||||
}
|
||||
return oneWalkAtATime(p, plans, onPath)
|
||||
}
|
||||
// **A walk lost to silence is resumed** (issue 1886): its tier was sent whole and only the gate after it failed it, every
|
||||
// **A walk lost to silence is resumed** (novox/hq ADR 0531, issue 1886): its tier was sent whole and only the gate after it failed it, every
|
||||
// machine it waited on silent; once they reported, it goes on from that gate.
|
||||
if len(stopped) == 0 && lostToSilence(p) {
|
||||
if q, found := newerOpenPlan(p, plans); found {
|
||||
@@ -718,11 +718,11 @@ func resumeStopped(p *inventory.Plan) string {
|
||||
}
|
||||
|
||||
// silentGateWords say, in a plan's note, that the gate between two tiers found every machine it waits on silent past
|
||||
// ApplySilentAfter, and failed the plan as lost (issue 1160): one text for the writer and the reader (lostToSilence).
|
||||
// ApplySilentAfter, and failed the plan as lost (issue 1160, ADR 0531): one text for the writer and the reader (lostToSilence).
|
||||
const silentGateWords = "every machine it waits on said nothing on its send within"
|
||||
|
||||
// lostToSilence is whether a plan failed only at the gate after its tier, every machine it waited on silent (issue
|
||||
// 1886): nothing in its tier failed to build, stopped rolling out or is still to ask — the look had sent the whole tier.
|
||||
// lostToSilence is whether a plan failed only at the gate after its tier, every machine it waited on silent (ADR 0531,
|
||||
// issue 1886): nothing in its tier failed to build, stopped rolling out or is still to ask — the look had sent the whole tier.
|
||||
func lostToSilence(p inventory.Plan) bool {
|
||||
if p.State != inventory.PlanFailed || p.Tier >= len(p.Tiers) || !strings.Contains(p.Note, silentGateWords) ||
|
||||
len(failedIn(p)) > 0 || len(stoppedRollouts(p)) > 0 {
|
||||
@@ -732,7 +732,7 @@ func lostToSilence(p inventory.Plan) bool {
|
||||
return asked == 0 && unasked == 0
|
||||
}
|
||||
|
||||
// resumeLost sets a walk lost to silence building again at the tier it failed after (issue 1886), for the next look to
|
||||
// resumeLost sets a walk lost to silence building again at the tier it failed after (ADR 0531, issue 1886), for the next look to
|
||||
// judge its gate again on the machines' reports, unless every machine its tier was sent to is still silent: then
|
||||
// nothing it needs is delivered anywhere yet, and the retry is refused as the gate would fail it again.
|
||||
func resumeLost(p *inventory.Plan, silent map[string]bool) (string, error) {
|
||||
|
||||
@@ -260,7 +260,7 @@ type gateNeed struct {
|
||||
}
|
||||
|
||||
// silentNodes is the machines a walk sent and heard nothing from past ApplySilentAfter, on whichever tier it sent
|
||||
// them (novox/hq ADR 0360 §5, issue 1160): the one rule both the gates between tiers and the walk's end read, through
|
||||
// them (novox/hq ADR 0360 §7, issue 1160): the one rule both the gates between tiers and the walk's end read, through
|
||||
// walkReports. A machine that reports on its send is not silent from then on.
|
||||
func silentNodes(p inventory.Plan, reports []inventory.Reported, now time.Time, prov inventory.ProvLookup) map[string]bool {
|
||||
_, _, silent := walkReports(p, reports, now, prov)
|
||||
@@ -272,7 +272,7 @@ func silentNodes(p inventory.Plan, reports []inventory.Reported, now time.Time,
|
||||
}
|
||||
|
||||
// withoutSilent is the machines of running that are not silent: a later tier is not sent to a machine the walk heard
|
||||
// nothing from, which keeps its want of the plan's builds for the send it gets when it is heard again (ADR 0360 §5).
|
||||
// nothing from, which keeps its want of the plan's builds for the send it gets when it is heard again (ADR 0360 §7).
|
||||
func withoutSilent(running []string, silent map[string]bool) []string {
|
||||
return slices.DeleteFunc(slices.Clone(running), func(n string) bool { return silent[n] })
|
||||
}
|
||||
@@ -1129,7 +1129,7 @@ func advanceOnce(ctx context.Context, open *stores, p *inventory.Plan,
|
||||
// being behind. Now every module of the tier whose first machine is the same is sent there in one
|
||||
// send, judged there by one gate — kept on the first of them, the others gated by it — and the rest
|
||||
// of the tier's machines are sent once, together, when the gates have passed.
|
||||
// **A machine silent past the bound is left as it was, on every tier** (novox/hq ADR 0360 §5, issue 1160): the
|
||||
// **A machine silent past the bound is left as it was, on every tier** (novox/hq ADR 0360 §7, issue 1160): the
|
||||
// walk's end names it, and the gates between tiers and the sends of the tiers after do not wait for it or go to it.
|
||||
allReports, err := inv.LastReports(ctx)
|
||||
if err != nil {
|
||||
@@ -1475,7 +1475,7 @@ func advanceOnce(ctx context.Context, open *stores, p *inventory.Plan,
|
||||
return changed, nil
|
||||
}
|
||||
}
|
||||
// **A walk ends on its machines' reports** (novox/hq ADR 0360 §4, §5): after its last tier, every machine it sent
|
||||
// **A walk ends on its machines' reports** (novox/hq ADR 0360 §4, §7): after its last tier, every machine it sent
|
||||
// has reported on that send, or is silent past ApplySilentAfter; never a health reading.
|
||||
end := ""
|
||||
if p.Tier == len(p.Tiers)-1 {
|
||||
@@ -1542,7 +1542,7 @@ func walkReports(p inventory.Plan, reports []inventory.Reported, now time.Time,
|
||||
carried[node] = append(carried[node], m)
|
||||
}
|
||||
}
|
||||
// **Each machine on the walk's last send to it** (issue 1886): a send carries the machine's whole declaration (ADR
|
||||
// **Each machine on the walk's last send to it** (novox/hq ADR 0531, issue 1886): a send carries the machine's whole declaration (ADR
|
||||
// 0221), so a report on the last one answers every earlier one, and the bound runs from it. Judged on every send
|
||||
// it had made, a walk whose tiers were sent hours apart — R4e, stopped at tier 1 and resumed — held tier 0's send of
|
||||
// 00:23 against tier 1's templates and named its machines silent 35 seconds after tier 1 was sent.
|
||||
|
||||
@@ -149,3 +149,25 @@ func TestALostWalkWithATierUnsentIsNotLostToSilence(t *testing.T) {
|
||||
t.Fatal("1886: a plan failed by a build was read as lost to silence")
|
||||
}
|
||||
}
|
||||
|
||||
// A walk lost to silence is refused its resume beside a newer open plan of its repository and branch, which supersedes
|
||||
// it, and beside a related open plan: one plan at a time (ADR 0531).
|
||||
func TestRetryRefusesAWalkLostToSilenceBesideANewerOrARelatedOpenPlan(t *testing.T) {
|
||||
p := r4eLost()
|
||||
created := time.Date(2026, 10, 22, 22, 15, 9, 0, time.UTC)
|
||||
p.Repository, p.Branch, p.Commit, p.Created = "novox/mesh-sdk", "main", "7aacbc16", created
|
||||
newerOpen := inventory.Plan{ID: "plan-newer", Repository: "novox/mesh-sdk", Branch: "main", Commit: "d00dfeed",
|
||||
Created: created.Add(time.Hour), State: inventory.PlanBuilding, Tiers: [][]string{{"zsh"}},
|
||||
Modules: map[string]*inventory.PlanModule{"zsh": {State: "asked"}}}
|
||||
if err := retryRefusal(p, []inventory.Plan{p, newerOpen}, ownPathOf(nil)); err == nil ||
|
||||
!strings.Contains(err.Error(), "plan-newer supersedes it") {
|
||||
t.Errorf("1886: a walk lost to silence was resumed under a newer open plan of its branch: %v", err)
|
||||
}
|
||||
beside := inventory.Plan{ID: "plan-beside", Repository: "novox/mesh-sdk", Branch: "release", Commit: "bbadbb2a",
|
||||
Created: created.Add(time.Hour), State: inventory.PlanBuilding, Tiers: [][]string{{"mesh-build-image"}},
|
||||
Modules: map[string]*inventory.PlanModule{"mesh-build-image": {State: "asked"}}}
|
||||
if err := retryRefusal(p, []inventory.Plan{p, beside}, ownPathOf(nil)); err == nil ||
|
||||
!strings.Contains(err.Error(), "one walk at a time") {
|
||||
t.Errorf("1886: a walk lost to silence was resumed beside a related open plan: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user