D2 (view): build_usage reads the build seats' steps and pauses as seat reads in the holder's state
The manifest reads seat:<seat>.steps and .pauses, which the grants part resolves, and the tools read <holder>.steps and <holder>.pauses. Builds: design 47 G A-82, A-128 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -422,6 +422,21 @@ func holderOf(ask func(key string, body any) (json.RawMessage, error)) func(seat
|
||||
}
|
||||
}
|
||||
|
||||
// ofHolder reads a build seat's state (`steps`, `pauses`) in the state of the seat's holder, `<holder>.<state>`, the holder found
|
||||
// as seatlist.HolderOf finds it (design 47 G A-128, A-126), as the manifest's `seat:<seat>.<state>` reads name it: the grants
|
||||
// part resolves a read only in that form. A seat whose holder cannot be found reads as an error naming it.
|
||||
func ofHolder(holder func(seat string) (string, bool), read func(name string) view.StateRead, state string) func(seat string) view.StateRead {
|
||||
return func(seat string) view.StateRead {
|
||||
module, ok := holder(seat)
|
||||
if !ok {
|
||||
fail := fmt.Errorf("the holder of %s is not found", seat)
|
||||
return view.StateRead{Keys: func() ([]string, error) { return nil, fail },
|
||||
Get: func(string) (json.RawMessage, error) { return nil, fail }}
|
||||
}
|
||||
return read(module + "." + state)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
logf := func(f string, a ...any) { fmt.Fprintf(os.Stderr, "[mesh-delivery-view-tools] "+f+"\n", a...) }
|
||||
// The catalog half per watched branch, followed by the bundle itself through meshcatalogclient's branch follower on
|
||||
@@ -463,8 +478,8 @@ func main() {
|
||||
}, holderOf(stdio.Ask))
|
||||
u := view.UsageReader{Haves: r.HavesState, Resolved: read(stdio.State("mesh-config.resolved")), Tries: read(stdio.State("mesh-delivery-checker.tries")),
|
||||
Seats: seats,
|
||||
StepsOf: func(seat string) view.StateRead { return read(stdio.State(seat + "." + view.StepsState)) },
|
||||
PausesOf: func(seat string) view.StateRead { return read(stdio.State(seat + "." + buildstep.PausesState)) },
|
||||
StepsOf: ofHolder(holderOf(stdio.Ask), func(name string) view.StateRead { return read(stdio.State(name)) }, view.StepsState),
|
||||
PausesOf: ofHolder(holderOf(stdio.Ask), func(name string) view.StateRead { return read(stdio.State(name)) }, buildstep.PausesState),
|
||||
Backlog: backlogOf(socket())}
|
||||
// view_first_views and view_first_view_again: where the view's process stands with its first views of the indexer's and
|
||||
// the assigner's states (ADR 0615 §6), and a re-read by hand.
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"mesh-delivery-view/internal/view"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
@@ -650,3 +651,22 @@ func TestABuildSeatsHolderIsTheOneTheSeatListNames(t *testing.T) {
|
||||
t.Error("a seat list that cannot be read names a holder")
|
||||
}
|
||||
}
|
||||
|
||||
// A build seat's steps and pauses are read in the state of the seat's holder, `<holder>.steps` and `<holder>.pauses`, the form
|
||||
// the manifest's `seat:<seat>.<state>` reads name and the grants part resolves (design 47 G A-82, A-128), never the seat's own name.
|
||||
func TestBuildSeatStatesAreReadInTheHoldersState(t *testing.T) {
|
||||
var named []string
|
||||
read := func(name string) view.StateRead {
|
||||
named = append(named, name)
|
||||
return view.StateRead{Keys: func() ([]string, error) { return nil, nil }}
|
||||
}
|
||||
holder := func(seat string) (string, bool) { return "acme-" + seat, seat != "node-build-node" }
|
||||
ofHolder(holder, read, view.StepsState)("node-build-go")
|
||||
ofHolder(holder, read, "pauses")("node-build-go")
|
||||
if want := []string{"acme-node-build-go.steps", "acme-node-build-go.pauses"}; !slices.Equal(named, want) {
|
||||
t.Errorf("read %v, want %v", named, want)
|
||||
}
|
||||
if _, err := ofHolder(holder, read, view.StepsState)("node-build-node").Keys(); err == nil {
|
||||
t.Error("a seat with no holder reads without an error")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ func TestManifestIsTakenAndReadsOnly(t *testing.T) { // 1134/AC7
|
||||
if m.Module != "mesh-delivery-view" {
|
||||
t.Errorf("module = %q", m.Module)
|
||||
}
|
||||
want := []string{"mesh-conditions.conditions", "mesh-config.resolved", "mesh-delivery-builder.build-log", "mesh-delivery-builder.builds", "mesh-delivery-checker.tries", "mesh-delivery-watchman.presence", "mesh-delivery-watchman.stuck", "mesh-healers.attempts", "mesh-provisioner.provisions", "mesh-vault.signers", "node-build-go.pauses", "node-build-go.steps", "node-build-image.pauses", "node-build-image.steps", "node-build-node.pauses", "node-build-node.steps", "node-engine.have"} // the build seats' states by seat, never a build module (design 47 G A-82); no read of the gate's source: each watched branch's is its verb source's (§512, A-173); // no reads of the indexer's or the assigner's states (ADR 0615 §1, DLV-M4); view_tiers reads the module graph and the provisioner's keys (ADR 0603 §6); view_status reads the keeper's conditions and the healers' attempts (1952/V1); build_usage reads the build modules' steps and pauses, mesh-config's capacities and the checker's tries; 1168/AC1, 1241/AC4, 1345/AC3, 1297/B8, B9
|
||||
want := []string{"mesh-conditions.conditions", "mesh-config.resolved", "mesh-delivery-builder.build-log", "mesh-delivery-builder.builds", "mesh-delivery-checker.tries", "mesh-delivery-watchman.presence", "mesh-delivery-watchman.stuck", "mesh-healers.attempts", "mesh-provisioner.provisions", "mesh-vault.signers", "node-engine.have", "seat:node-build-go.pauses", "seat:node-build-go.steps", "seat:node-build-image.pauses", "seat:node-build-image.steps", "seat:node-build-node.pauses", "seat:node-build-node.steps"} // the build seats' states by seat, never a build module (design 47 G A-82); no read of the gate's source: each watched branch's is its verb source's (§512, A-173); // no reads of the indexer's or the assigner's states (ADR 0615 §1, DLV-M4); view_tiers reads the module graph and the provisioner's keys (ADR 0603 §6); view_status reads the keeper's conditions and the healers' attempts (1952/V1); build_usage reads the build modules' steps and pauses, mesh-config's capacities and the checker's tries; 1168/AC1, 1241/AC4, 1345/AC3, 1297/B8, B9
|
||||
got := slices.Clone(m.Reads)
|
||||
slices.Sort(got)
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
|
||||
@@ -121,12 +121,12 @@
|
||||
"seat:node-engine.manifest-reads"
|
||||
],
|
||||
"reads": [
|
||||
"node-build-go.pauses",
|
||||
"node-build-go.steps",
|
||||
"node-build-image.pauses",
|
||||
"node-build-image.steps",
|
||||
"node-build-node.pauses",
|
||||
"node-build-node.steps",
|
||||
"seat:node-build-go.pauses",
|
||||
"seat:node-build-go.steps",
|
||||
"seat:node-build-image.pauses",
|
||||
"seat:node-build-image.steps",
|
||||
"seat:node-build-node.pauses",
|
||||
"seat:node-build-node.steps",
|
||||
"mesh-config.resolved",
|
||||
"mesh-delivery-builder.build-log",
|
||||
"mesh-delivery-builder.builds",
|
||||
|
||||
Reference in New Issue
Block a user