diff --git a/contracts/go/clients/meshcatalogclient/catalog_test.go b/contracts/go/clients/meshcatalogclient/catalog_test.go index d8a60d74..9ec9030c 100644 --- a/contracts/go/clients/meshcatalogclient/catalog_test.go +++ b/contracts/go/clients/meshcatalogclient/catalog_test.go @@ -35,13 +35,6 @@ func TestDigestAndFingerprintSetKeepTheirForms(t *testing.T) { } // A manifest and a module are read back as written, and each rule of the old values is kept: a refusal names its reason. -// The holder's states others read keep the addresses the manifests' `reads` and the first views name today. -func TestTheHoldersReadAddressesAreTheOnesTheManifestsName(t *testing.T) { - if Module != "mesh-delivery-indexer" || ModulesRead != "mesh-delivery-indexer.modules" || ManifestsRead != "mesh-delivery-indexer.manifests" { - t.Errorf("the holder %q reads %q and %q", Module, ModulesRead, ManifestsRead) - } -} - func TestManifestAndModuleValuesKeepTheirRules(t *testing.T) { if _, err := ManifestsKey("abc"); err == nil || !strings.Contains(err.Error(), `"abc"`) { t.Errorf("ManifestsKey(abc) = %v", err) diff --git a/contracts/go/clients/meshcatalogclient/module.go b/contracts/go/clients/meshcatalogclient/module.go index b07eada7..d07b3692 100644 --- a/contracts/go/clients/meshcatalogclient/module.go +++ b/contracts/go/clients/meshcatalogclient/module.go @@ -10,15 +10,6 @@ import ( "git.novox.be/novox/mesh-sdk/go/keys" ) -// Module is the module that holds the seat mesh-catalog, and the two states of its others read, by the address a -// manifest's `reads` and a first view name them: the modules the trunk holds and their manifests. A reader names them here, -// never by the holder's literal name. -const ( - Module = "mesh-delivery-indexer" - ModulesRead = Module + ".modules" - ManifestsRead = Module + ".manifests" -) - // RootPath is a `modules` value's path when the module's manifest is its repository's root. const RootPath = "." diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go index 8e2446e9..9ec95629 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go @@ -7,6 +7,19 @@ import ( "encoding/json" "errors" "fmt" + "io" + "maps" + "mesh-delivery-assigner/internal/buckets" + "mesh-delivery-assigner/internal/placement" + "mesh-delivery-assigner/internal/puts" + "os" + "path/filepath" + "slices" + "strings" + "sync" + "testing" + "time" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" @@ -17,22 +30,13 @@ import ( "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate" "git.novox.be/novox/mesh-delivery/sdk/buildstep" - "io" - "maps" - "mesh-delivery-assigner/internal/buckets" - "mesh-delivery-assigner/internal/puts" - "os" - "path/filepath" - "slices" - "strings" - "sync" - "testing" - "time" "github.com/nats-io/nats-server/v2/server" "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" + "mesh-delivery-assigner/internal/judge" + occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" @@ -44,7 +48,6 @@ import ( "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/process" "git.novox.be/novox/mesh-sdk/go/seatdef" - "mesh-delivery-assigner/internal/judge" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" @@ -122,7 +125,7 @@ func startBed(t *testing.T, leaveOut string) *bed { // event names the engine's machine last, so the filter is the event with every machine (mesh-grants buscompose // machineEvent; the grants part's own test holds the derivation). if _, err := js.CreateOrUpdateConsumer(ctx, "EVENTS", jetstream.ConsumerConfig{Durable: "n1_mesh-delivery-assigner", - FilterSubjects: []string{enginereads.SubjectPrefix + "*", "mesh.mod." + meshcatalogclient.Module + ".event.views.>"}, AckPolicy: jetstream.AckExplicitPolicy}); err != nil { + FilterSubjects: []string{enginereads.SubjectPrefix + "*", "mesh.mod." + buckets.IndexerModule + ".event.views.>"}, AckPolicy: jetstream.AckExplicitPolicy}); err != nil { t.Fatal(err) } // The operator-channel seat's stream of conditions, which the assigner says its conditions on. @@ -387,7 +390,7 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { firstViewBound, firstViewWait = 300*time.Millisecond, 50*time.Millisecond t.Cleanup(func() { indexerLate, firstViewBound, firstViewWait = nil, 0, 0 }) for _, name := range append(append([]string{}, readBuckets...), watched...) { - if strings.HasPrefix(name, meshcatalogclient.Module+"_") { + if strings.HasPrefix(name, buckets.IndexerModule+"_") { t.Errorf("the assigner reads the indexer's state %s itself", name) } } @@ -427,10 +430,10 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { "seat-holders": {"n1.node-tools"}, "wants": {"n1.mesh-grants"}, }) - graphKey := meshconditionsclient.Key(meshconditionsclient.ScopeModule, mmac.Module+"."+meshcatalogclient.Module+"."+graph.State, views.UnansweredKind) + graphKey := meshconditionsclient.Key(meshconditionsclient.ScopeModule, placement.Module+"."+buckets.IndexerModule+"."+graph.State, views.UnansweredKind) graphRaised := func() bool { e, err := b.buckets[assign.FindingsBucket].Get(b.ctx, graphKey) - return err == nil && strings.Contains(string(e.Value()), meshcatalogclient.Module+".graph") + return err == nil && strings.Contains(string(e.Value()), buckets.IndexerModule+".graph") } for deadline := time.Now().Add(10 * time.Second); !graphRaised(); time.Sleep(50 * time.Millisecond) { if time.Now().After(deadline) { @@ -1092,7 +1095,7 @@ func (s bedStore) kv(state string) jetstream.KeyValue { if strings.Contains(state, ".") { return s.b.buckets[strings.Replace(state, ".", "_", 1)] } - return s.b.buckets[mmac.Module+"_"+state] + return s.b.buckets[placement.Module+"_"+state] } func (s bedStore) get(state, key string) ([]byte, uint64, bool, error) { @@ -1127,7 +1130,7 @@ func (s bedStore) history(string, string) ([]stdio.StateRevision, error) { retur // and declined, writes nothing and is withdrawn. func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) { b := startBed(t, "") - if _, err := b.js.CreateStream(b.ctx, jetstream.StreamConfig{Name: "MOD_" + mmac.Module + "_placement", + if _, err := b.js.CreateStream(b.ctx, jetstream.StreamConfig{Name: "MOD_" + placement.Module + "_placement", Subjects: placementSubjects()}); err != nil { // the seat's four events: the views family has a stream of its own t.Fatal(err) } @@ -1379,8 +1382,8 @@ func (b *bed) viewsHold(t *testing.T, state, key string) { t.Fatal(err) } for deadline := time.Now().Add(20 * time.Second); ; time.Sleep(50 * time.Millisecond) { - f := &views.Follower{Owner: mmac.Module, Tool: state, State: state, Ask: func(context.Context, string) (views.Answer, error) { - return views.FirstView(mmac.Module, state, src(kv), src(marks), "", time.Now()) + f := &views.Follower{Owner: placement.Module, Tool: state, State: state, Ask: func(context.Context, string) (views.Answer, error) { + return views.FirstView(placement.Module, state, src(kv), src(marks), "", time.Now()) }} if err := f.Start(b.ctx); err != nil { t.Fatal(err) @@ -1389,7 +1392,7 @@ func (b *bed) viewsHold(t *testing.T, state, key string) { gap := false for seq := info.State.FirstSeq; seq > 0 && seq <= info.State.LastSeq; seq++ { m, err := st.GetMsg(b.ctx, seq) - if owner, _ := views.OwnerOfEvent(m.Subject); err != nil || owner != mmac.Module || views.StateOfEvent(m.Subject) != state { + if owner, _ := views.OwnerOfEvent(m.Subject); err != nil || owner != placement.Module || views.StateOfEvent(m.Subject) != state { continue } e, err := views.DecodeEvent(m.Data) @@ -1447,7 +1450,7 @@ func (s bedSource) Get(key string) (*views.Entry, bool, error) { func placementSubjects() []string { var out []string for _, e := range mma.Events() { - out = append(out, process.ModuleStreamSubject(mmac.Module, e)) + out = append(out, process.ModuleStreamSubject(placement.Module, e)) } return out } @@ -1461,11 +1464,11 @@ var indexerLate chan struct{} // read by the assigner's durable consumer; and its first-view tools of the three answered from the buckets at their marks. func serveIndexer(t *testing.T, b *bed, nc *nats.Conn) { t.Helper() - marks, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: meshcatalogclient.Module + "_" + views.MarksState, History: 1}) + marks, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: buckets.IndexerModule + "_" + views.MarksState, History: 1}) if err != nil { t.Fatal(err) } - em := views.Emitter{Owner: meshcatalogclient.Module, Subject: process.Account{Node: "n1", Module: meshcatalogclient.Module}.EventSubject, + em := views.Emitter{Owner: buckets.IndexerModule, Subject: process.Account{Node: "n1", Module: buckets.IndexerModule}.EventSubject, Publish: views.JetStreamPublish(b.js), Marks: marks} for state, bucket := range indexerFirstViews { kv, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: bucket, History: 5}) @@ -1490,7 +1493,7 @@ func serveIndexer(t *testing.T, b *bed, nc *nats.Conn) { After string `json:"after"` } _ = json.Unmarshal(m.Data, &args) - a, err := views.FirstView(meshcatalogclient.Module, state, bedSource{b.ctx, kv}, bedSource{b.ctx, marks}, args.After, time.Now()) + a, err := views.FirstView(buckets.IndexerModule, state, bedSource{b.ctx, kv}, bedSource{b.ctx, marks}, args.After, time.Now()) out := map[string]any{"result": a, "node": "n0"} if err != nil { out = map[string]any{"error": err.Error()} @@ -1550,7 +1553,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] outR, outW := io.Pipe() t.Cleanup(func() { inW.Close(); outW.Close() }) go func() { - _ = stdio.ServeOn(mmac.Module, viewTools(func(k string) string { return env[k] }, state, time.Now), inR, outW) + _ = stdio.ServeOn(placement.Module, viewTools(func(k string) string { return env[k] }, state, time.Now), inR, outW) }() answers := make(chan map[string]any, 16) go func() { @@ -1571,7 +1574,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] t.Fatal(err) } t.Cleanup(nc.Close) - sub, err := nc.Subscribe("mesh.mod."+mmac.Module+".call.*.*", func(msg *nats.Msg) { + sub, err := nc.Subscribe("mesh.mod."+placement.Module+".call.*.*", func(msg *nats.Msg) { one <- struct{}{} defer func() { <-one }() tokens := strings.Split(msg.Subject, ".") @@ -1603,7 +1606,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] ask := func(user, tool string) (views.Answer, error) { return views.AskVia(func(key string, body any) (json.RawMessage, error) { data, _ := json.Marshal(body) - msg, err := nc.Request("mesh.mod."+mmac.Module+".call."+tool+"."+strings.ReplaceAll(user, ".", "~"), data, 5*time.Second) + msg, err := nc.Request("mesh.mod."+placement.Module+".call."+tool+"."+strings.ReplaceAll(user, ".", "~"), data, 5*time.Second) if err != nil { return nil, err } @@ -1619,7 +1622,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][] t.Errorf("%s's first view of %s before any new-form state: %v", user, tool, err) case slices.Contains(allowed, user): keys, _ := b.buckets[viewedStates[tool]].Keys(b.ctx) - if a.Owner != mmac.Module || a.State != tool || len(a.Values) != len(keys) { + if a.Owner != placement.Module || a.State != tool || len(a.Values) != len(keys) { t.Errorf("%s's first view of %s = %+v, the state holds %v", user, tool, a, keys) } case err == nil || !strings.Contains(err.Error(), "refused"): diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go index 775b8969..15fcc4b4 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/main.go @@ -10,10 +10,10 @@ import ( "context" "errors" "fmt" - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "io" "log" "mesh-delivery-assigner/internal/buckets" + "mesh-delivery-assigner/internal/placement" "os" "os/signal" "slices" @@ -85,7 +85,7 @@ var ownBuckets = []string{buckets.Asks, buckets.Differences, const engineReadsState = "engine-reads" // engineReadsBucket is that state's bucket. -const engineReadsBucket = mmac.Module + "_" + engineReadsState +const engineReadsBucket = placement.Module + "_" + engineReadsState // seatBuckets are the seat's states, new with it: until the controller has made them from the manifest and the bus grants // them, the assigner starts without them and binds each once the bus says it was created (issue 1790's kind). @@ -512,7 +512,7 @@ var PutsReopenEvery = time.Minute // (ADR 0437 clause 9). func sayVia(ctx context.Context, js jetstream.JetStream) func(oc.Condition) error { return func(c oc.Condition) error { - subject, err := occ.ConditionSubject(mmac.Module) + subject, err := occ.ConditionSubject(placement.Module) if err != nil { return err } @@ -529,7 +529,7 @@ func sayVia(ctx context.Context, js jetstream.JetStream) func(oc.Condition) erro // consumer on EVENTS, and asks the node it names again; the hub also hands the indexer's views to the followers of // indexerViews, and starts once both are registered. func hearReadsChanged(ctx context.Context, js jetstream.JetStream, hub *process.EventHub, reads *enginereads.Keeper, findings assign.Findings, logf func(string, ...any)) { - account := process.Account{Node: thisNode, Module: mmac.Module} + account := process.Account{Node: thisNode, Module: placement.Module} w := notHeardWriter(findings, logf) handle := func(m jetstream.Msg) { if err := m.Ack(); err != nil { diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go index 81e1bccb..28698e28 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go @@ -6,6 +6,13 @@ import ( "encoding/json" "errors" "fmt" + "mesh-delivery-assigner/internal/buckets" + "mesh-delivery-assigner/internal/puts" + "slices" + "strings" + "testing" + "time" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" wdc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshwatchdogsclient" mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" @@ -16,12 +23,6 @@ import ( "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate" - "mesh-delivery-assigner/internal/buckets" - "mesh-delivery-assigner/internal/puts" - "slices" - "strings" - "testing" - "time" "github.com/nats-io/nats.go/jetstream" @@ -363,7 +364,7 @@ func putOfTheBus(t *testing.T) { buildKV.values[bkey] = built modules := mem() modules.values["nats"] = mod - s := newPutTools(memStore{putsState: putsKV, builds.BuilderModule + ".builds": buildKV, meshcatalogclient.Module + ".modules": modules}) + s := newPutTools(memStore{putsState: putsKV, builds.BuilderModule + ".builds": buildKV, buckets.IndexerModule + ".modules": modules}) s.now = func() time.Time { return now } was := answerWithin answerWithin = 0 @@ -1130,7 +1131,7 @@ func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) { if err != nil { t.Fatal(err) } - p.w.put(graph.Bucket, module, raw) + p.w.put(buckets.Graph, module, raw) } g := p.moduleGraph() if got := keptInvokes(g, "caller"); !slices.Equal(got, []string{"seat:x.v"}) || keptInvokes(g, "unknown") != nil { diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go index 7d2a6e3a..306c4b7d 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go @@ -5,19 +5,21 @@ import ( "encoding/json" "errors" "fmt" + "maps" + "mesh-delivery-assigner/internal/buckets" + "mesh-delivery-assigner/internal/placement" + "reflect" + "slices" + "sort" + "strings" + "time" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient" mdc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" - "maps" - "mesh-delivery-assigner/internal/buckets" - "reflect" - "slices" - "sort" - "strings" - "time" "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" @@ -56,7 +58,7 @@ func seatPublisher(ctx context.Context, js jetstream.JetStream, node string) pub } msg := nats.NewMsg(seatdef.EventSubject(mma.Seat, event)) msg.Header.Set("x-event-id", id) - msg.Header.Set("x-source", mmac.Module) + msg.Header.Set("x-source", placement.Module) msg.Header.Set("x-node", node) msg.Header.Set("x-time", time.Now().UTC().Format(time.RFC3339Nano)) msg.Header.Set("content-type", "application/json") diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go index 701aeb1a..1626c940 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go @@ -4,14 +4,16 @@ import ( "encoding/json" "errors" "fmt" - "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" - "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "mesh-delivery-assigner/internal/buckets" "slices" "sort" "strings" "time" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" + "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" stdio "git.novox.be/novox/mesh-sdk/go" @@ -42,7 +44,7 @@ func (runtimeStore) history(state, key string) ([]stdio.StateRevision, error) { // The states the verbs read, as the runtime names them: the seat's own by their local names, the others' // `.`. const ( - modulesState = meshcatalogclient.Module + ".modules" + modulesState = buckets.IndexerModule + ".modules" haveState = "node-engine.have" ) diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go index 899a82e1..d99bb859 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go @@ -4,8 +4,7 @@ import ( "encoding/json" "errors" "fmt" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" + "mesh-delivery-assigner/internal/buckets" "mesh-delivery-assigner/internal/puts" "os" "regexp" @@ -15,6 +14,9 @@ import ( "sync" "time" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" + stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-delivery/sdk/enginereads" @@ -76,7 +78,7 @@ func (s *putTools) version(module, version string) (string, error) { v := strings.ToLower(strings.TrimSpace(version)) switch { case v == "newest": - raw, _, found, err := s.st.get(meshcatalogclient.ModulesRead, module) + raw, _, found, err := s.st.get(buckets.ModulesRead, module) if err != nil { return "", fmt.Errorf("the indexer's modules cannot be read: %w", err) } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go index c3607709..bc3f55e6 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/verbs.go @@ -2,11 +2,12 @@ package main import ( "context" - "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "mesh-delivery-assigner/internal/buckets" "slices" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" + "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-delivery/sdk/graph" @@ -23,7 +24,7 @@ import ( // does not decode is left out, so its module waits on no verb. func (p *passer) moduleGraph() graph.Graph { g := graph.Graph{} - for key, raw := range p.w.read(graph.Bucket) { + for key, raw := range p.w.read(buckets.Graph) { module, err := graph.ParseKey(key) if err != nil { continue diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go index 02b4dc2f..4f125394 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/views.go @@ -3,9 +3,8 @@ package main import ( "context" "encoding/json" - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "mesh-delivery-assigner/internal/buckets" + "mesh-delivery-assigner/internal/placement" "slices" "time" @@ -28,7 +27,7 @@ import ( ) // marksBucket is the assigner's state of what its views family said each state up to. -var marksBucket = mmac.Module + "_" + views.MarksState +var marksBucket = placement.Module + "_" + views.MarksState // viewedTool is one tool over one state of the assigner's. type viewedTool struct{ tool, state, words string } @@ -67,13 +66,13 @@ func viewTools(getenv func(string) string, state func(string) views.Source, now marks := state(views.MarksState) var out []stdio.Tool for _, t := range firstViewTools { - out = append(out, views.FirstViewTool(mmac.Module, t.tool, t.state, t.words, views.ParseCallers(getenv(views.CallersEnv(t.tool))), state(t.state), marks, now)) + out = append(out, views.FirstViewTool(placement.Module, t.tool, t.state, t.words, views.ParseCallers(getenv(views.CallersEnv(t.tool))), state(t.state), marks, now)) } for _, t := range readTools { - out = append(out, views.ReadTool(mmac.Module, t.tool, t.state, t.words, state(t.state), marks, now)) + out = append(out, views.ReadTool(placement.Module, t.tool, t.state, t.words, state(t.state), marks, now)) } // Its own first views, of the indexer's manifests, modules and graph (DLV-F3r, ADR 0631 §2): read, and asked again by hand. - return append(out, views.StatusTools(mmac.Module, "assigner_first_views", "assigner_first_view_again", stdio.State(views.StatusState), meshhandactsclient.Recorder{Ask: stdio.Ask}, now)...) + return append(out, views.StatusTools(placement.Module, "assigner_first_views", "assigner_first_view_again", stdio.State(views.StatusState), meshhandactsclient.Recorder{Ask: stdio.Ask}, now)...) } func keptSource(name string) views.Source { return views.KeptSource{State: stdio.State(name)} } @@ -85,7 +84,7 @@ func startViews(ctx context.Context, js jetstream.JetStream, nc process.Subscrib if findings.Put == nil { return } - if err := viewFindings(findings).Put(views.TooLargeFinding(mmac.Module, state, key, size, time.Now())); err != nil { + if err := viewFindings(findings).Put(views.TooLargeFinding(placement.Module, state, key, size, time.Now())); err != nil { logf("views: the finding of %s.%s too large is not written: %v", state, key, err) } } @@ -110,7 +109,7 @@ func startViews(ctx context.Context, js jetstream.JetStream, nc process.Subscrib // viewsEmitter is the assigner's emitter of its views family: a change not said past views.Bound is its finding // view-unsaid, in its findings (review round 2); with no findings state it is said in the log only. func viewsEmitter(js jetstream.JetStream, account process.Account, mk jetstream.KeyValue, findings assign.Findings, tooLarge func(string, string, int), logf func(string, ...any)) views.Emitter { - em := views.Emitter{Owner: mmac.Module, Subject: account.EventSubject, Publish: views.JetStreamPublish(js), Marks: mk, TooLarge: tooLarge, Logf: logf} + em := views.Emitter{Owner: placement.Module, Subject: account.EventSubject, Publish: views.JetStreamPublish(js), Marks: mk, TooLarge: tooLarge, Logf: logf} if findings.Put != nil && findings.Delete != nil { em.Findings = viewFindings(findings) } @@ -123,7 +122,7 @@ func viewFindings(f assign.Findings) views.FindingWriter { } // firstViewsBucket is the assigner's own state of its first views (views.StatusState). -var firstViewsBucket = mmac.Module + "_" + views.StatusState +var firstViewsBucket = placement.Module + "_" + views.StatusState // indexerViews are the assigner's first views of the indexer's manifests, modules and module graph (ADR 0615 §1, // ADR 0621 §2, ADR 0631; DLV-F2r): asked at the start through the indexer's tools, then followed on indexer-views, asking once more on a gap; @@ -141,7 +140,7 @@ type indexerViews struct { // indexerFirstViews are the indexer's states the assigner takes by first view and the views family, each by the name of // the indexer's bucket the world keeps it under: manifests and modules (ADR 0621 §2), and the module graph, whose verb // edges a want waits on (ADR 0614 §2, §3; ADR 0631 §1). -var indexerFirstViews = map[string]string{"manifests": buckets.Manifests, "modules": buckets.Modules, graph.State: graph.Bucket} +var indexerFirstViews = map[string]string{"manifests": buckets.Manifests, "modules": buckets.Modules, graph.State: buckets.Graph} // firstViewBound and firstViewWait are each first view's bound before its condition is raised, and its first wait // between two failed asks; zero is the views package's (views.Bound, two minutes, ADR 0615 §6; and a first wait of five @@ -155,7 +154,7 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle if iv.findings.Put == nil { return } - f := views.UnansweredFinding(mmac.Module, s, time.Now()) + f := views.UnansweredFinding(placement.Module, s, time.Now()) var err error if raised { err = viewFindings(iv.findings).Put(f) @@ -170,8 +169,8 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle var all []*views.Follower for state, bucket := range indexerFirstViews { bucket := bucket - tool := meshcatalogclient.Module + "." + state - f := &views.Follower{Owner: meshcatalogclient.Module, Tool: tool, State: state, Ask: views.AskVia(iv.call, tool), Logf: iv.logf, + tool := buckets.IndexerModule + "." + state + f := &views.Follower{Owner: buckets.IndexerModule, Tool: tool, State: state, Ask: views.AskVia(iv.call, tool), Logf: iv.logf, Bound: firstViewBound, Wait: firstViewWait, Raise: func(s views.Status) { finding(s, true) }, Clear: func(s views.Status) { finding(s, false) }, Changed: func(key string, value json.RawMessage, deleted bool, at time.Time) { @@ -202,7 +201,7 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle // Not heard, the indexer's views family is the finding family-not-heard until it binds (ADR 0615 §5): the handler is // registered on the module's hub, which the assigner starts once every handler is. _ = notHeardWriter(iv.findings, iv.logf).Bind(process.EventsStream, "the indexer's manifests, modules and graph are the first views' alone until the assigner starts again", func() error { - return iv.hub.Handle("mesh.mod."+meshcatalogclient.Module+".event."+views.EventPrefix+"*", views.Hear(ctx, followers, iv.logf)) + return iv.hub.Handle("mesh.mod."+buckets.IndexerModule+".event."+views.EventPrefix+"*", views.Hear(ctx, followers, iv.logf)) }) return len(all) } @@ -210,7 +209,7 @@ func (iv *indexerViews) start(ctx context.Context, w *world, wake func(), settle // notHeardWriter writes the assigner's finding of a family it does not hear into its findings (heard.Writer); with no // findings state it is said in the log alone. func notHeardWriter(findings assign.Findings, logf func(string, ...any)) heard.Writer { - w := heard.Writer{Observer: mmac.Module, Logf: logf, Put: findings.Put} + w := heard.Writer{Observer: placement.Module, Logf: logf, Put: findings.Put} if findings.Delete != nil { w.Delete = func(key string) error { if keys, err := findings.Keys(); err == nil && !slices.Contains(keys, key) { diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go index 5b9874e5..608f0ceb 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go @@ -4,17 +4,18 @@ import ( "encoding/json" "errors" "fmt" - "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" - meshhandacts "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhandacts" - "git.novox.be/novox/mesh-contracts/placement/go/seats/meshwants" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" - "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "mesh-delivery-assigner/internal/buckets" "mesh-delivery-assigner/internal/puts" "sort" "strconv" "time" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" + meshhandacts "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhandacts" + "git.novox.be/novox/mesh-contracts/placement/go/seats/meshwants" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" + mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" stdio "git.novox.be/novox/mesh-sdk/go" @@ -32,7 +33,7 @@ import ( // The states the verbs read, as the runtime names them. const ( policiesState = buckets.PoliciesState - manifestsState = meshcatalogclient.Module + ".manifests" + manifestsState = buckets.IndexerModule + ".manifests" // PolicyChangedEvent is the seat's event of a person's policy set or taken back. PolicyChangedEvent = "policy-changed" // busStepCause is the cause the bus's step is recorded under in the hand-act log. diff --git a/modules/mesh-delivery-assigner/internal/assign/asks.go b/modules/mesh-delivery-assigner/internal/assign/asks.go index 064a5049..78d315a9 100644 --- a/modules/mesh-delivery-assigner/internal/assign/asks.go +++ b/modules/mesh-delivery-assigner/internal/assign/asks.go @@ -2,14 +2,15 @@ package assign import ( "fmt" - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" + "mesh-delivery-assigner/internal/placement" + "regexp" + "strings" + "time" + mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" - "regexp" - "strings" - "time" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" @@ -68,7 +69,7 @@ func RestoreAsk(key, node, module, fp, words string, now time.Time) asks.Ask { // words, under the assigner's own name (ADR 0437 clause 9), keyed by the held fingerprint. needsYou is true for a module holding // data, whose restore ask waits for the operator. func HeldCondition(module, fp, node, words string, raised, needsYou bool) oc.Condition { - key := mmac.Module + ".held." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) + key := placement.Module + ".held." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared} @@ -91,7 +92,7 @@ func HeldCondition(module, fp, node, words string, raised, needsYou bool) oc.Con // the node keeps its want. It names the node, the module, fp and the have's words, keyed by node and module, and is cleared // (raised false) once the node no longer fails alone. func NodeFailedCondition(node, module, fp string, f NodeFailure, raised bool) oc.Condition { - key := mmac.Module + ".failed-alone." + node + "." + module + key := placement.Module + ".failed-alone." + node + "." + module subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, @@ -114,7 +115,7 @@ func NodeFailedCondition(node, module, fp string, f NodeFailure, raised bool) oc // naming the module, the node and the rule holding its first want back with the rule's words, under the assigner's own name keyed by // node and module, and cleared (raised false) when the node has a want for it again. func NeitherCondition(node, module string, h Holding, raised bool) oc.Condition { - key := mmac.Module + ".neither." + node + "." + module + key := placement.Module + ".neither." + node + "." + module subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, @@ -236,7 +237,7 @@ func BackupAsk(key, node, module, fp, digest, words string, asking int, now time // BackupCondition is the condition raised when a backup before an apply fails and the module is held on the node (ADR 0539 §16), // naming the node, the module and the backup's words; cleared under the same key. func BackupCondition(node, module, fp, words string, raised bool) oc.Condition { - key := mmac.Module + ".backup." + node + "." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) + key := placement.Module + ".backup." + node + "." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared} diff --git a/modules/mesh-delivery-assigner/internal/assign/asks_test.go b/modules/mesh-delivery-assigner/internal/assign/asks_test.go index bfe79022..07bc607f 100644 --- a/modules/mesh-delivery-assigner/internal/assign/asks_test.go +++ b/modules/mesh-delivery-assigner/internal/assign/asks_test.go @@ -2,18 +2,19 @@ package assign import ( "fmt" - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" - mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-view/viewstate" + "mesh-delivery-assigner/internal/placement" "mesh-delivery-assigner/internal/puts" "slices" "strings" "testing" "time" + mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-view/viewstate" + mcc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient" mcseat "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" @@ -161,7 +162,7 @@ func saidConditionsAreFindings(t *testing.T) { t.Fatalf("%s: %v", c.key, err) } got, ok := puts[c.key] - if !ok || got.Severity != c.raised.Severity || got.Headline != c.raised.Headline || got.Observer != mmac.Module || + if !ok || got.Severity != c.raised.Severity || got.Headline != c.raised.Headline || got.Observer != placement.Module || got.Subject.Machine != c.raised.Subject.Machine || said != 0 { t.Fatalf("%s: finding %+v (written %v), said %d", c.key, got, puts, said) } diff --git a/modules/mesh-delivery-assigner/internal/assign/findings.go b/modules/mesh-delivery-assigner/internal/assign/findings.go index 10b3c16c..aa6c610f 100644 --- a/modules/mesh-delivery-assigner/internal/assign/findings.go +++ b/modules/mesh-delivery-assigner/internal/assign/findings.go @@ -3,7 +3,7 @@ package assign import ( "errors" "fmt" - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" + "mesh-delivery-assigner/internal/placement" "strings" "time" @@ -21,13 +21,13 @@ import ( // assigner no longer says it straight (never both). // FindingsBucket is the assigner's findings. -var FindingsBucket = mcc.FindingsBucket(mmac.Module) +var FindingsBucket = mcc.FindingsBucket(placement.Module) // FindingOf is a said condition as a finding: its key `..`, from the condition's own key // `mesh-delivery-assigner..` (the subject's id when the key names none), its words unchanged. raised is false for // a clear, whose key is to be deleted; value is nil then. func FindingOf(c oc.Condition, at time.Time) (key string, value []byte, raised bool, err error) { - rest, ok := strings.CutPrefix(c.Key, mmac.Module+".") + rest, ok := strings.CutPrefix(c.Key, placement.Module+".") if !ok || rest == "" { return "", nil, false, fmt.Errorf("the condition %q is not the assigner's", c.Key) } @@ -56,7 +56,7 @@ func FindingOf(c oc.Condition, at time.Time) (key string, value []byte, raised b } f := mcc.Observation{Scope: scope, ID: id, Kind: kind, Machine: c.Subject.Machine, Severity: string(c.Severity), Summary: summary, Headline: c.Headline, Explanation: c.Explanation, Resolved: c.Resolved, Needs: c.Needs, Actions: actions, - Source: "assigner." + kind}.Finding(mmac.Module, "", at) + Source: "assigner." + kind}.Finding(placement.Module, "", at) value, err = mcc.EncodeFinding(f) return key, value, true, err } diff --git a/modules/mesh-delivery-assigner/internal/assign/placement.go b/modules/mesh-delivery-assigner/internal/assign/placement.go index 523fb446..c0726cca 100644 --- a/modules/mesh-delivery-assigner/internal/assign/placement.go +++ b/modules/mesh-delivery-assigner/internal/assign/placement.go @@ -1,7 +1,7 @@ package assign import ( - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" + "mesh-delivery-assigner/internal/placement" "strings" occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" @@ -11,8 +11,8 @@ import ( // SeatWaitsCondition is the assigner's word on the seat mesh-placement while a state of the seat is not bound (ADR 0567 // §1): raised naming each, cleared when none is left. func SeatWaitsCondition(unbound []string) oc.Condition { - key := mmac.Module + ".seat-states" - subject := oc.ConditionSubject{Scope: "module", ID: mmac.Module} + key := placement.Module + ".seat-states" + subject := oc.ConditionSubject{Scope: "module", ID: placement.Module} if len(unbound) == 0 { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, Resolved: "the seat mesh-placement holds all its states."} } diff --git a/modules/mesh-delivery-assigner/internal/assign/policy.go b/modules/mesh-delivery-assigner/internal/assign/policy.go index 348eff29..b62e1b4b 100644 --- a/modules/mesh-delivery-assigner/internal/assign/policy.go +++ b/modules/mesh-delivery-assigner/internal/assign/policy.go @@ -3,8 +3,8 @@ package assign import ( "encoding/json" "fmt" - mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "mesh-delivery-assigner/internal/buckets" + "mesh-delivery-assigner/internal/placement" "sort" "strings" "time" @@ -20,7 +20,7 @@ import ( // catalogue.Upgrade: a person's choice over the module's word, its irreplaceable data and the default, the bus as any module (ADR 0601 §1). // PoliciesBucket is the assigner's state `policies`. -var PoliciesBucket = mmac.Module + "_" + buckets.PoliciesState +var PoliciesBucket = placement.Module + "_" + buckets.PoliciesState // DecodePolicies reads the policies state's values by key (the module); a value that cannot be read is left out, named. func DecodePolicies(values map[string][]byte) (map[string]catalogue.PersonPolicy, []string) { @@ -76,7 +76,7 @@ func ProvisionFailedFinding(key string, p meshprovisionerclient.Provision, at ti // encode is the observation as the assigner's finding at at, in the seat's layout. func encode(o mcc.Observation, at time.Time) ([]byte, error) { - return mcc.EncodeFinding(o.Finding(mmac.Module, "", at)) + return mcc.EncodeFinding(o.Finding(placement.Module, "", at)) } func also(provider, consumer string) []string { diff --git a/modules/mesh-delivery-assigner/internal/assign/seat.go b/modules/mesh-delivery-assigner/internal/assign/seat.go index 056980bc..a3d3abc1 100644 --- a/modules/mesh-delivery-assigner/internal/assign/seat.go +++ b/modules/mesh-delivery-assigner/internal/assign/seat.go @@ -2,18 +2,20 @@ package assign import ( "fmt" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" "maps" "slices" "strings" "time" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks" + occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient" oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel" mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" + "mesh-delivery-assigner/internal/placement" plc "mesh-delivery-assigner/internal/placement" ) @@ -177,7 +179,7 @@ const ( // CallClearedCondition clears the condition of a refused controller call a previous process raised, for its pair (node and // module, or node and provision for a pin). func CallClearedCondition(kind, node, module string) oc.Condition { - return oc.Condition{Key: mmac.Module + "." + kind + "." + node + "." + module, + return oc.Condition{Key: placement.Module + "." + kind + "." + node + "." + module, Subject: oc.ConditionSubject{Scope: "module", ID: module, Machine: node}, State: occ.StateCleared, Resolved: "the assigner calls no verb of the controller any more: placement is the one source."} } diff --git a/modules/mesh-delivery-assigner/internal/buckets/buckets.go b/modules/mesh-delivery-assigner/internal/buckets/buckets.go index c0fe39eb..4aa589ce 100644 --- a/modules/mesh-delivery-assigner/internal/buckets/buckets.go +++ b/modules/mesh-delivery-assigner/internal/buckets/buckets.go @@ -36,9 +36,16 @@ const ( Have = "node-engine_" + nodeengine.StateHave // ComposedRead is the family of the node-engine's composed states, one bucket per node. ComposedRead = "mesh-host." + nodeengine.StateComposed - // Modules and Manifests are the indexer's. - Modules = "mesh-delivery-indexer_" + catalog.StateModules - Manifests = "mesh-delivery-indexer_" + catalog.StateManifests + // IndexerModule is the holder of the seat mesh-catalog, named from this module's manifest (`consumes` its views, `invokes` + // its tools; TestTheIndexerIsTheManifests), since no client names a holder (ADR 0625 §4). + IndexerModule = "mesh-delivery-indexer" + // Modules, Manifests and Graph are the indexer's buckets; ModulesRead and ManifestsRead the addresses of the states + // modules and manifests as a first view names them. + Modules = IndexerModule + "_" + catalog.StateModules + Manifests = IndexerModule + "_" + catalog.StateManifests + Graph = IndexerModule + "_graph" + ModulesRead = IndexerModule + "." + catalog.StateModules + ManifestsRead = IndexerModule + "." + catalog.StateManifests // Presence holds each part's presence and the node's. Presence = "mesh-delivery-watchman_" + watchdogs.StatePresence // Source and Merges are the gate's. diff --git a/modules/mesh-delivery-builder/cmd/mesh-delivery-builder/names.go b/modules/mesh-delivery-builder/cmd/mesh-delivery-builder/names.go index 5c425e7b..62852567 100644 --- a/modules/mesh-delivery-builder/cmd/mesh-delivery-builder/names.go +++ b/modules/mesh-delivery-builder/cmd/mesh-delivery-builder/names.go @@ -1,7 +1,6 @@ package main import ( - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/buildrun" ) @@ -16,7 +15,7 @@ const ( forgeBridgeModule = "mesh-delivery-forge-bridge" // indexerModule is the holder of the states modules, manifests, candidates and packages the builder follows. - indexerModule = meshcatalogclient.Module + indexerModule = "mesh-delivery-indexer" // assignerModule is the holder of the state placement. assignerModule = buildrun.AssignerModule diff --git a/modules/mesh-delivery-checker/internal/check/names.go b/modules/mesh-delivery-checker/internal/check/names.go index fbc015d7..d34e2bee 100644 --- a/modules/mesh-delivery-checker/internal/check/names.go +++ b/modules/mesh-delivery-checker/internal/check/names.go @@ -3,7 +3,6 @@ package check import ( "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshwatchdogs" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdelivery" checker "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdeliverychecker" @@ -28,7 +27,7 @@ const ( // IndexerModule holds the seat mesh-catalog's states, which the checker follows by their views (consumes: // mesh-delivery-indexer.views.*). - IndexerModule = meshcatalogclient.Module + IndexerModule = "mesh-delivery-indexer" CandidatesBucket = IndexerModule + "_" + meshcatalog.StateCandidates ModulesBucket = IndexerModule + "_" + meshcatalog.StateModules ManifestsBucket = IndexerModule + "_" + meshcatalog.StateManifests diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go index f2730bb3..83c883ea 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/integration_test.go @@ -86,7 +86,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15 }, func(ctx context.Context, js jetstream.JetStream) { // The states and the stream the controller makes from the indexer's manifest (old sections, ADR 0595 §11). for bucket, history := range map[string]uint8{index.PendingBucket: 1, index.VerdictsBucket: index.VerdictsHistory, - graph.Bucket: 1, index.TakenBucket: 1, index.PackagesBucket: 1, + index.GraphBucket: 1, index.TakenBucket: 1, index.PackagesBucket: 1, index.SeatDefinitionsBucket: 1, index.RequirementsBucket: 1, findingsBucket: 1, index.HoldsBucket: 1} { if _, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: bucket, History: history}); err != nil { t.Fatal(err) @@ -284,7 +284,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15 if _, ok := get(index.VerdictsBucket, own.Manifest); !ok { t.Errorf("the verdict on the indexer's manifest %s is not written", own.Manifest) } - if gk, _ := graph.Key(ix); !func() bool { _, ok := get(graph.Bucket, gk); return ok }() { + if gk, _ := graph.Key(ix); !func() bool { _, ok := get(index.GraphBucket, gk); return ok }() { t.Errorf("the indexer's key %s of the module graph is not written", gk) } repoKey, _ := trunk.RepositoryKey(m1.Repository) diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go index 67c38476..257105cf 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go @@ -31,7 +31,6 @@ import ( stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-delivery/sdk/enginereads" - "git.novox.be/novox/mesh-delivery/sdk/graph" "git.novox.be/novox/mesh-sdk/go/process" "mesh-delivery-indexer/internal/index" @@ -402,7 +401,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro // appears; until then indexer_requirements answers none, and the builder's floor waits on its answer. requirements := process.AwaitBucket(ctx, js, conn, index.RequirementsBucket, "what consumers require is not kept", logger.Printf) // The module graph (ADR 0603 §2): a state this delivery brings, bound when it appears; until then no graph is written. - graph := process.AwaitBucket(ctx, js, conn, graph.Bucket, "no module graph is written", logger.Printf) + graph := process.AwaitBucket(ctx, js, conn, index.GraphBucket, "no module graph is written", logger.Printf) findings := process.AwaitBucket(ctx, js, conn, findingsBucket, "no finding of the indexer is written", logger.Printf) // The seat definitions (design 26, DLV-I17): a state this delivery brings, bound when it appears; until then none is kept. seatDefs := process.AwaitBucket(ctx, js, conn, index.SeatDefinitionsBucket, "no seat definition is kept", logger.Printf) diff --git a/modules/mesh-delivery-indexer/internal/index/candidates.go b/modules/mesh-delivery-indexer/internal/index/candidates.go index b73e14b5..0b998d89 100644 --- a/modules/mesh-delivery-indexer/internal/index/candidates.go +++ b/modules/mesh-delivery-indexer/internal/index/candidates.go @@ -92,7 +92,7 @@ type Indexer struct { ReadFile func(ctx context.Context, repository, sha, path string) ([]byte, error) // SaySeatDefinition says seat-definition-changed (seatdefs.go); nil says nothing. SaySeatDefinition func(ctx context.Context, c SeatDefinitionChanged) error - // Graph is the module graph's state (graph.Bucket, graph.go; novox/hq ADR 0603 §2); nil writes no graph. + // Graph is the module graph's state (GraphBucket, graph.go; novox/hq ADR 0603 §2); nil writes no graph. Graph Store // Files asks the forge for every blob under each directory at a commit, by directory then path relative to it, each // with its git object id (gitea.gitea_commit_trees with files): the listing a package's digest is computed from. diff --git a/modules/mesh-delivery-indexer/internal/index/graph.go b/modules/mesh-delivery-indexer/internal/index/graph.go index 7d95d2d1..199f9f7d 100644 --- a/modules/mesh-delivery-indexer/internal/index/graph.go +++ b/modules/mesh-delivery-indexer/internal/index/graph.go @@ -16,7 +16,7 @@ import ( ) // The module graph (novox/hq ADR 0603 §2): at every recompute the indexer writes, in its state graph -// (graph.Bucket), one key per module it holds the inputs of, its build, provision and verb edges as that recompute +// (GraphBucket), one key per module it holds the inputs of, its build, provision and verb edges as that recompute // computed them (ADR 0614 §1), the verb edges on a cycle left out over the whole graph (§3), and deletes the key of a module the modules state no longer holds. A key is written only when its value // changes, so its history of 5 is five changes of the module's edges. The delivery view, the checker and the seat // mesh-catalog's verbs read it; nothing stores an order (ADR 0603 §1). diff --git a/modules/mesh-delivery-indexer/internal/index/names.go b/modules/mesh-delivery-indexer/internal/index/names.go index a3ed09da..3e35db84 100644 --- a/modules/mesh-delivery-indexer/internal/index/names.go +++ b/modules/mesh-delivery-indexer/internal/index/names.go @@ -1,10 +1,12 @@ package index +import "git.novox.be/novox/mesh-delivery/sdk/graph" + // The holders, states and buckets the indexer names, taken from its own manifest (module.json: its name, its `state`, its // `reads`) and from the manifests of the holders it reads; a unit row checks them against the manifest // (TestTheNamesAreTheManifests). No contract names a holder (novox/hq ADR 0625 §4, ADR 0634 §1). const ( - // Module is the indexer's own name; the catalog client's Module is the readers' name for it. + // Module is the indexer's own name; each reader names it from its own manifest. Module = "mesh-delivery-indexer" // The indexer's own states, with the revisions each keeps per key (module.json `state`). @@ -17,6 +19,8 @@ const ( ManifestsState = "manifests" ManifestsBucket = Module + "_" + ManifestsState ManifestsHistory = 1 + // GraphBucket is the bucket of the state graph (sdk/graph names the state, not its holder). + GraphBucket = Module + "_" + graph.State // VerdictsState and VerdictsBucket are in verdicts.go. VerdictsHistory = 5 PredefinedState = "predefined" diff --git a/modules/mesh-delivery-indexer/internal/index/views.go b/modules/mesh-delivery-indexer/internal/index/views.go index ab2ca0ab..3bb6ac6f 100644 --- a/modules/mesh-delivery-indexer/internal/index/views.go +++ b/modules/mesh-delivery-indexer/internal/index/views.go @@ -48,7 +48,7 @@ var ViewedStates = map[string]string{ ConfigCandidatesState: ConfigCandidatesBucket, "candidates": CandidatesBucket, PackagesState: PackagesBucket, - graph.State: graph.Bucket, + graph.State: GraphBucket, HeardState: HeardBucket, "taken": TakenBucket, mcc.FindingsState: mcc.FindingsBucket(Module), diff --git a/modules/mesh-delivery-indexer/manifest_test.go b/modules/mesh-delivery-indexer/manifest_test.go index 706f75c1..f1d26614 100644 --- a/modules/mesh-delivery-indexer/manifest_test.go +++ b/modules/mesh-delivery-indexer/manifest_test.go @@ -125,7 +125,7 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build t.Errorf("the indexer names itself %q, its manifest's module is %q", index.Module, m.Module) } for bucket, history := range map[string]int{index.CandidatesBucket: index.CandidatesHistory, index.ModulesBucket: index.ModulesHistory, index.ManifestsBucket: index.ManifestsHistory, - index.VerdictsBucket: index.VerdictsHistory, index.PackagesBucket: index.PackagesHistory, index.TakenBucket: 1, index.PredefinedBucket: 5, index.ConfigCandidatesBucket: 5} { + index.VerdictsBucket: index.VerdictsHistory, index.PackagesBucket: index.PackagesHistory, index.TakenBucket: 1, index.PredefinedBucket: 5, index.ConfigCandidatesBucket: 5, index.GraphBucket: graph.History} { if !slices.ContainsFunc(m.State, func(st state) bool { return m.Module+"_"+st.Name == bucket && st.History == history }) { t.Errorf("the indexer names its bucket %s with %d revisions, its manifest's states are %+v", bucket, history, m.State) } diff --git a/modules/mesh-delivery-view/internal/view/names.go b/modules/mesh-delivery-view/internal/view/names.go index 6b0ee441..9b4bbe4d 100644 --- a/modules/mesh-delivery-view/internal/view/names.go +++ b/modules/mesh-delivery-view/internal/view/names.go @@ -3,7 +3,6 @@ package view import ( "fmt" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-delivery/sdk/trunk" "git.novox.be/novox/mesh-sdk/go/keys" @@ -13,7 +12,7 @@ import ( // `consumes`); a unit row checks them against it (TestTheNamesAreTheManifests). No contract names a holder (novox/hq // ADR 0625 §4, ADR 0634 §1). The indexer's module and its reads are the catalog client's. const ( - IndexerModule = meshcatalogclient.Module + IndexerModule = "mesh-delivery-indexer" AssignerModule = "mesh-delivery-assigner" WatchmanModule = "mesh-delivery-watchman" GateModule = "mesh-delivery-gate" diff --git a/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/integration_test.go b/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/integration_test.go index ca458306..00d33173 100644 --- a/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/integration_test.go +++ b/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/integration_test.go @@ -68,7 +68,7 @@ accounts { func serveOwners(t *testing.T, ctx context.Context, js jetstream.JetStream, nc *nats.Conn) { t.Helper() viewstest.Serve(t, ctx, js, nc, watch.AssignerModule, wantsState, watch.AssignerModule+".assigner_read_wants", "n1_"+watch.WatchmanModule) - viewstest.Serve(t, ctx, js, nc, meshcatalogclient.Module, modulesState, meshcatalogclient.Module+".indexer_read_modules", "n1_"+watch.WatchmanModule) + viewstest.Serve(t, ctx, js, nc, watch.IndexerModule, modulesState, watch.IndexerModule+".indexer_read_modules", "n1_"+watch.WatchmanModule) } // TestWatchmanWhole starts the program the way the node does (its entry, run, with its environment and a broker file) diff --git a/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/main.go b/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/main.go index 0a62fdf9..68a41c13 100644 --- a/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/main.go +++ b/modules/mesh-delivery-watchman/cmd/mesh-delivery-watchman/main.go @@ -10,7 +10,6 @@ import ( "encoding/json" "errors" "fmt" - sdkfindings "git.novox.be/novox/mesh-delivery/sdk/findings" "io" "log" "os" @@ -19,6 +18,8 @@ import ( "syscall" "time" + sdkfindings "git.novox.be/novox/mesh-delivery/sdk/findings" + "git.novox.be/novox/mesh-sdk/go/process" "git.novox.be/novox/mesh-sdk/go/views" @@ -27,7 +28,6 @@ import ( "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshwatchdogsclient" "git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-indexer/takein" "git.novox.be/novox/mesh-delivery/sdk/buildstep" @@ -247,7 +247,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro if err != nil { return err } - modules, err := reader.Follow(meshcatalogclient.Module, modulesState, meshcatalogclient.Module+".indexer_read_modules") + modules, err := reader.Follow(watch.IndexerModule, modulesState, watch.IndexerModule+".indexer_read_modules") if err != nil { return err } @@ -455,7 +455,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro w.TakeInCaughtUp() } } - if err := hub.Handle("mesh.mod."+meshcatalogclient.Module+".event.take-in.*", func(m jetstream.Msg) { takeInHeard(w, m, logger.Printf) }); err != nil { + if err := hub.Handle("mesh.mod."+watch.IndexerModule+".event.take-in.*", func(m jetstream.Msg) { takeInHeard(w, m, logger.Printf) }); err != nil { return err } } @@ -535,7 +535,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro const eventsStream = "EVENTS" // pendingTool is the indexer's tool that answers the waits it holds (ADR 0633 §5), as the view asks it. -const pendingTool = meshcatalogclient.Module + ".indexer_pending" +const pendingTool = watch.IndexerModule + ".indexer_pending" // seedTakeIn asks the indexer the waits it holds now and starts each (Watchman.SeedTakeIn). An indexer that does not // answer is said: the waits are then known only from the events heard after. diff --git a/modules/mesh-delivery-watchman/internal/watch/names.go b/modules/mesh-delivery-watchman/internal/watch/names.go index 8d547735..12fe3141 100644 --- a/modules/mesh-delivery-watchman/internal/watch/names.go +++ b/modules/mesh-delivery-watchman/internal/watch/names.go @@ -2,7 +2,6 @@ package watch import ( meshwatchdogs "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshwatchdogs" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" ) // The holders and buckets the watchman names, taken from its own manifest (module.json: its name, its `reads`, its @@ -11,7 +10,9 @@ import ( const ( WatchmanModule = "mesh-delivery-watchman" AssignerModule = "mesh-delivery-assigner" - builderModule = "mesh-delivery-builder" + // IndexerModule is the holder of the seat mesh-catalog, named from this module's manifest (consumes and invokes of mesh-delivery-indexer). + IndexerModule = "mesh-delivery-indexer" + builderModule = "mesh-delivery-builder" // The watchman's own states of the seat mesh-watchdogs. PresenceBucket = WatchmanModule + "_" + meshwatchdogs.StatePresence @@ -26,7 +27,7 @@ const ( // AssignerWantsBucket is the assigner's state wants, followed by its views family (consumes: mesh-delivery-assigner.views.wants). AssignerWantsBucket = AssignerModule + "_wants" // ModulesBucket is the indexer's state modules, followed by its views family (consumes: mesh-delivery-indexer.views.modules). - ModulesBucket = meshcatalogclient.Module + "_modules" + ModulesBucket = IndexerModule + "_modules" ) // The findings a value of another part is raised as, named by their words. diff --git a/modules/mesh-delivery-watchman/manifest_test.go b/modules/mesh-delivery-watchman/manifest_test.go index cff47de1..29f4c4d3 100644 --- a/modules/mesh-delivery-watchman/manifest_test.go +++ b/modules/mesh-delivery-watchman/manifest_test.go @@ -11,8 +11,6 @@ import ( "strings" "testing" - "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" - "mesh-delivery-watchman/internal/watch" ) @@ -162,7 +160,7 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6 "wants": {watch.AssignerWantsBucket, bucket(m.Consumes, "mesh-delivery-assigner.views.wants")}, "modules": {watch.ModulesBucket, bucket(m.Consumes, "mesh-delivery-indexer.views.modules")}, "assigner": {watch.AssignerModule + ".assigner_read_wants", entry(m.Invokes, "mesh-delivery-assigner.assigner_read_wants")}, - "indexer": {meshcatalogclient.Module + ".indexer_pending", entry(m.Invokes, "mesh-delivery-indexer.indexer_pending")}, + "indexer": {watch.IndexerModule + ".indexer_pending", entry(m.Invokes, "mesh-delivery-indexer.indexer_pending")}, } { if row.got != row.want { t.Errorf("the name for %s is %q, its manifest's is %q", name, row.got, row.want) diff --git a/modules/mesh-grants/internal/buscompose/buscompose_test.go b/modules/mesh-grants/internal/buscompose/buscompose_test.go index a07dda3e..5cc5a3f2 100644 --- a/modules/mesh-grants/internal/buscompose/buscompose_test.go +++ b/modules/mesh-grants/internal/buscompose/buscompose_test.go @@ -2,9 +2,6 @@ package buscompose import ( "encoding/json" - "git.novox.be/novox/mesh-contracts/go/seats/meshbroker" - "git.novox.be/novox/mesh-contracts/identity-and-access/go/seats/meshnodeenroller" - "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" "maps" "os" "path/filepath" @@ -14,9 +11,12 @@ import ( "testing" "time" + "git.novox.be/novox/mesh-contracts/go/seats/meshbroker" + "git.novox.be/novox/mesh-contracts/identity-and-access/go/seats/meshnodeenroller" + "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner" + "git.novox.be/novox/mesh-contracts/identity-and-access/go/clients/meshvaultclient" "git.novox.be/novox/mesh-contracts/identity-and-access/go/seats/meshvault" - "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-sdk/go/announce" "git.novox.be/novox/mesh-sdk/go/catalogue" @@ -60,7 +60,7 @@ func TestTheCopiedComposerComposesAsTheControllers(t *testing.T) { // ADR 0567 §3, §9: a node reads every key of the seat's placement and its candidates (it composes with the whole // proposal laid over), and none of its open proposals; it writes neither. reads := strings.Join(NodeComposeReads("laptop"), " ") - for bucket, granted := range map[string]bool{meshmoduleassignerclient.PlacementBucket: true, PlacementCandidatesBucket: true, + for bucket, granted := range map[string]bool{PlacementBucket: true, PlacementCandidatesBucket: true, PlacementProposalsBucket: false} { if strings.Contains(reads, "$JS.API.DIRECT.GET.KV_"+bucket+".>") != granted || strings.Contains(reads, "$KV."+bucket+".laptop") { t.Errorf("a node is granted %s: %v, want %v", bucket, !granted, granted) @@ -655,7 +655,7 @@ func healthChecks(t *testing.T) { {Module: "mesh-provisioner-client", ProvisionsNode: true}, // ADR 0571 clauses 2, 4 (issue 1955): the seat mesh-artifact-sweep says artifacts-gone; the assigner keeps seat-holders. {Module: "artifact-store-tools", Holds: []Seat{{Name: "mesh-artifact-sweep", Emits: []string{"artifacts-gone"}}}, - Reads: []string{meshmoduleassignerclient.SeatHoldersRead}}, + Reads: []string{SeatHoldersRead}}, {Module: AssignerModule, State: []Bucket{bucket(AssignerModule, meshmoduleassigner.StateSeatHolders)}}, // ADR 0571 clause 3: disk-load keeps the readings; the backup holder reads them. // ADR 0577 clause 1: and it reads its own node's keys of the node-engine's data items, which restic may not. diff --git a/modules/mesh-grants/internal/buscompose/names.go b/modules/mesh-grants/internal/buscompose/names.go index bbb5cf61..7544f911 100644 --- a/modules/mesh-grants/internal/buscompose/names.go +++ b/modules/mesh-grants/internal/buscompose/names.go @@ -15,6 +15,13 @@ const ( // EnrolmentModule is the module holding the seat mesh-node-enroller. EnrolmentModule = "mesh-enrolment" + // PlacementBucket and SeatHoldersBucket are the assigner's states placement and seat-holders (reads: + // mesh-delivery-assigner.placement; the seat-holders state is read as a named reader), PlacementRead the address of the first. + PlacementBucket = AssignerModule + "_placement" + PlacementRead = AssignerModule + ".placement" + SeatHoldersRead = AssignerModule + ".seat-holders" + SeatHoldersBucket = AssignerModule + "_seat-holders" + AssignerWantsBucket = AssignerModule + "_wants" PlacementCandidatesBucket = AssignerModule + "_candidates" PlacementProposalsBucket = AssignerModule + "_placement-proposals" diff --git a/modules/mesh-grants/internal/buscompose/names_test.go b/modules/mesh-grants/internal/buscompose/names_test.go index 50144180..f2f830e1 100644 --- a/modules/mesh-grants/internal/buscompose/names_test.go +++ b/modules/mesh-grants/internal/buscompose/names_test.go @@ -32,6 +32,7 @@ func namesAreTheManifests(t *testing.T) { {"reads", HaveBucket[:strings.Index(HaveBucket, "_")] + ".have", HaveBucket}, {"reads", NodeLoginsRead, NodeLoginsBucket}, {"reads", EnrolmentsRead, EnrolmentsBucket}, + {"invokes", PlacementRead, PlacementBucket}, {"invokes", AssignerModule + ".wants", AssignerWantsBucket}, {"invokes", IndexerModule + ".modules", ModulesBucket}, {"invokes", IndexerModule + ".manifests", ManifestsBucket}, diff --git a/modules/mesh-grants/internal/buscompose/provisioner.go b/modules/mesh-grants/internal/buscompose/provisioner.go index c175520c..ba6ad5ed 100644 --- a/modules/mesh-grants/internal/buscompose/provisioner.go +++ b/modules/mesh-grants/internal/buscompose/provisioner.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" - "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" "git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient" "github.com/nats-io/nats.go" @@ -49,7 +48,7 @@ var ProvisionerReads = []string{ConfigResolvedBucket} // reason** (2026-10-30 recovery, issue 774): the client V3 watches every machine's plans to bind a provider's // consumers, and granted only its own machine's keys it read none. ADR 0570 clause 3 has providers act on the seat's // provision keys instead; once the client does, plans go back to its own machine's keys. -var ProvisionerReadsWhole = []string{meshmoduleassignerclient.PlacementBucket, meshprovisionerclient.PlansBucket} +var ProvisionerReadsWhole = []string{PlacementBucket, meshprovisionerclient.PlansBucket} // BoundState is a providing module's state of entries, one per consumer (mesh-sdk go/provider, issue 678): a // consumer's machine's client reads its own keys of it, `..[.]`, to fill diff --git a/modules/mesh-grants/internal/buscompose/state.go b/modules/mesh-grants/internal/buscompose/state.go index 733b6159..c13d6619 100644 --- a/modules/mesh-grants/internal/buscompose/state.go +++ b/modules/mesh-grants/internal/buscompose/state.go @@ -2,12 +2,12 @@ package buscompose import ( "fmt" - "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" - "git.novox.be/novox/mesh-sdk/go/announce" "slices" "strings" "time" + + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" + "git.novox.be/novox/mesh-sdk/go/announce" ) // A module's state on the bus (novox/hq ADR 0201, design 32 §4, design 25 §3). @@ -341,7 +341,7 @@ const ResolvedBucket = "mesh-config_resolved" // secret. Reads only; the node is checked as every subject token is by the caller's principal. func NodeComposeReads(node string) []string { var out []string - for _, bucket := range []string{meshmoduleassignerclient.PlacementBucket, PlacementCandidatesBucket, ModulesBucket, + for _, bucket := range []string{PlacementBucket, PlacementCandidatesBucket, ModulesBucket, ManifestsBucket, builds.BuilderBuildsBucket} { out = append(out, readGrants(bucket, "")...) } @@ -351,7 +351,7 @@ func NodeComposeReads(node string) []string { // NodeComposeAdvisories are the stream-created advisories of the seat mesh-placement's placement and candidates // (ADR 0567 §9): what a node agent hears to bind each once it is made. Those two and no wider. func NodeComposeAdvisories() []string { - return []string{StreamCreatedAdvisory(meshmoduleassignerclient.PlacementBucket), StreamCreatedAdvisory(PlacementCandidatesBucket)} + return []string{StreamCreatedAdvisory(PlacementBucket), StreamCreatedAdvisory(PlacementCandidatesBucket)} } // ServedReadGrants is the read of each key of mesh-config's resolved values named, `..` diff --git a/modules/mesh-grants/internal/grants/inputs.go b/modules/mesh-grants/internal/grants/inputs.go index d1409733..b1ac5c87 100644 --- a/modules/mesh-grants/internal/grants/inputs.go +++ b/modules/mesh-grants/internal/grants/inputs.go @@ -17,6 +17,8 @@ import ( "sync" "time" + "mesh-grants/internal/buscompose" + "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" "git.novox.be/novox/mesh-contracts/identity-and-access/go/clients/meshvaultclient" @@ -30,7 +32,6 @@ import ( "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds" "git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay" "git.novox.be/novox/mesh-sdk/go/catalogue" - "mesh-grants/internal/buscompose" ) // The states of other parts the grants part reads, as its manifest's reads name them (`.`). @@ -48,7 +49,7 @@ const ( ReadAccounts = "mesh-vault.bus-accounts" // ReadPlacement is the seat mesh-placement's placement (ADR 0567 §1, §9): each node's modules and the seats // they hold. - ReadPlacement = meshmoduleassignerclient.PlacementRead + ReadPlacement = buscompose.PlacementRead // ReadEnrolments is the seat mesh-enrolment's open enrolments, read as a named reader (ADR 0587 §2, §4): a key at // live or redeeming composes the user enrol.. ReadEnrolments = buscompose.EnrolmentsRead diff --git a/sdk/graph/graph.go b/sdk/graph/graph.go index 1291e558..c8086e93 100644 --- a/sdk/graph/graph.go +++ b/sdk/graph/graph.go @@ -65,12 +65,10 @@ func checkRepository(repository string) error { // operator, 2026-11-03: no graph-related code in mesh-sdk, only contracts). It names no module. const ( - // State is the name of the indexer's state of the module graph, as its manifest declares it, and Bucket its - // bucket: one key per module (Key). - State = "graph" - Bucket = meshcatalogclient.Module + "_" + State - // Read is the line a reader's manifest names in `reads` to read the graph. - Read = meshcatalogclient.Module + "." + State + // State is the name of the indexer's state of the module graph, as its manifest declares it: one key per module + // (Key). Its bucket is the holder's name and the state's, which the indexer and each reader name from its own + // manifest, never this package (ADR 0625 §4). + State = "graph" // History is the revisions the graph state keeps per key (ADR 0603 §2). History = 5 ) diff --git a/sdk/graph/graph_test.go b/sdk/graph/graph_test.go index 6e55adf5..71bef6ce 100644 --- a/sdk/graph/graph_test.go +++ b/sdk/graph/graph_test.go @@ -213,7 +213,7 @@ func sampleNode() Node { // nodeValues: a node round-trips with its lists sorted, an unknown version is refused, a node that does not hold is // refused naming why, and the state is the indexer's graph (ADR 0603 §2). func nodeValues(t *testing.T) { - if Bucket != "mesh-delivery-indexer_graph" || Read != "mesh-delivery-indexer.graph" || History != 5 || State != "graph" { + if History != 5 || State != "graph" { t.Error("the graph's state differs from the decided layout") } g := sampleNode()