DLV-B3: a name waiting on its floor is the builder's finding floor-silent, cleared once all three sources answer
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -10,6 +10,8 @@ import (
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
"git.novox.be/novox/mesh-sdk/go/process"
|
||||
|
||||
"mesh-delivery-builder/internal/versions"
|
||||
)
|
||||
|
||||
// findingsBucket is the builder's findings (novox/hq ADR 0564 §2): what it sees wrong now, written at its raise and
|
||||
@@ -119,3 +121,19 @@ func (f *findings) clear(ctx context.Context, kind, scope, id string) {
|
||||
f.logf("the finding %s cannot be cleared: %v", key, err)
|
||||
}
|
||||
}
|
||||
|
||||
// floorSaid is the floor finding (design 51 *Health and conditions*: a floor source silent): raised for a name waiting on
|
||||
// its floor, about that name, cleared once all three sources answered.
|
||||
func (f *findings) floorSaid(ctx context.Context) func(versions.FloorWait, bool) {
|
||||
return func(w versions.FloorWait, raised bool) {
|
||||
if !raised {
|
||||
f.clear(ctx, versions.FloorSilent, health.ScopeModule, w.Name)
|
||||
return
|
||||
}
|
||||
f.raise(ctx, finding{kind: versions.FloorSilent, scope: health.ScopeModule, id: w.Name, summary: w.Finding(),
|
||||
headline: "A version's floor is not known",
|
||||
explanation: "The builder numbers a name only once its registry seat, the forge bridge's tags and the indexer's requirements all answered; one of them did not.",
|
||||
resolved: "All three answered.",
|
||||
needs: "builder_floor_waits names the silent source; builder_floor_again asks again by hand."})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,8 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
||||
// The builder numbers each trunk build at its claim (novox/hq design 51 *The versions*): its state versions, bound once
|
||||
// the bus holds it; the floor's three sources asked as its own account; each new number said as version.numbered.
|
||||
versionsKV := process.AwaitBucket(ctx, js, conn, versions.Bucket, "no trunk build is numbered: each is built unnumbered and published by its digest", logger.Printf)
|
||||
floorWaits := &versions.FloorWaits{Logf: logger.Printf}
|
||||
found := &findings{kv: process.AwaitBucket(ctx, js, conn, findingsBucket, "the builder's findings are said in its log only", logger.Printf), logf: logger.Printf, now: time.Now}
|
||||
floorWaits := &versions.FloorWaits{Logf: logger.Printf, Said: found.floorSaid(context.WithoutCancel(ctx))}
|
||||
// The names waiting on their floor are kept in the state floor-waits (DLV-B4): a restarted builder takes them in, so
|
||||
// their silent sources' events still wake them; until the state is bound they are kept here only.
|
||||
process.AwaitBucket(ctx, js, conn, versions.FloorWaitsBucket, "the names waiting on their floor are kept in memory only, and builder_floor_waits shows none", logger.Printf).
|
||||
@@ -168,7 +169,6 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
||||
b.Trunk = trunks.head
|
||||
// The builder's log (ADR 0571 §1): each build's start and end in its module log `build-log`, read by the view, the
|
||||
// indexer and the assigner through their reads, and by the operator's command nox builds through the tool builder_builds_since.
|
||||
found := &findings{kv: process.AwaitBucket(ctx, js, conn, findingsBucket, "the builder's findings are said in its log only", logger.Printf), logf: logger.Printf, now: time.Now}
|
||||
b.Log = func(e delivery.BuildLogEntry) {
|
||||
if err := appendLog(context.WithoutCancel(ctx), js, cred, e); err != nil {
|
||||
logger.Printf("%v", err)
|
||||
|
||||
@@ -217,6 +217,17 @@ func aFailedTrunkBuildIsAFinding(t *testing.T) {
|
||||
if _, ok := st.vals[key]; ok {
|
||||
t.Error("a later done trunk build leaves build-failed")
|
||||
}
|
||||
// The floor finding: raised while a name waits on its floor, cleared once it is known.
|
||||
fw := &versions.FloorWaits{Said: f.floorSaid(context.Background())}
|
||||
fw.Wait("m/lib", versions.SeatGoPackages, "", versions.Floor{Silent: []string{versions.SourceTags}}, nil, time.Unix(0, 0))
|
||||
floorKey := health.FindingKey(health.ScopeModule, "m/lib", versions.FloorSilent)
|
||||
if got, err := health.DecodeFinding(st.vals[floorKey]); err != nil || !strings.Contains(got.Summary, "bridge_tags did not answer") {
|
||||
t.Fatalf("the floor finding = %+v, %v", got, err)
|
||||
}
|
||||
fw.Answered("m/lib")
|
||||
if _, ok := st.vals[floorKey]; ok {
|
||||
t.Error("a known floor leaves floor-silent")
|
||||
}
|
||||
}
|
||||
|
||||
// memFindings is a findings bucket in memory.
|
||||
|
||||
@@ -135,8 +135,13 @@ type FloorWaits struct {
|
||||
keeper FloorKeeper
|
||||
// Logf says a wait that could not be kept; nil says nothing.
|
||||
Logf func(string, ...any)
|
||||
// Said is told each wait recorded (raised) and each answered (not raised): the builder's finding floor-silent.
|
||||
Said func(w FloorWait, raised bool)
|
||||
}
|
||||
|
||||
// FloorSilent is the kind of the floor finding.
|
||||
const FloorSilent = "floor-silent"
|
||||
|
||||
// Keep binds the state: the waits it holds that are not known here are taken in (a restarted builder's), every wait
|
||||
// known here is written to it, and every change from now on is.
|
||||
func (fw *FloorWaits) Keep(k FloorKeeper, held []FloorWait) {
|
||||
@@ -200,16 +205,22 @@ func (fw *FloorWaits) Wait(name, seat, holder string, f Floor, why map[string]st
|
||||
k := fw.keeper
|
||||
fw.mu.Unlock()
|
||||
fw.put(k, w)
|
||||
if fw.Said != nil {
|
||||
fw.Said(w, true)
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
// Answered drops name: its floor is known. It says whether the name waited, so its finding is cleared.
|
||||
func (fw *FloorWaits) Answered(name string) bool {
|
||||
fw.mu.Lock()
|
||||
_, had := fw.waits[name]
|
||||
w, had := fw.waits[name]
|
||||
delete(fw.waits, name)
|
||||
k := fw.keeper
|
||||
fw.mu.Unlock()
|
||||
if had && fw.Said != nil {
|
||||
fw.Said(w, false)
|
||||
}
|
||||
if had && k != nil {
|
||||
if err := k.Delete(FloorWaitKey(name)); err != nil && fw.Logf != nil {
|
||||
fw.Logf("the floor wait of %s is not cleared from %s: %v", name, FloorWaitsState, err)
|
||||
|
||||
Reference in New Issue
Block a user