No client names a holder: each reader keeps its own constant, held to its manifest (ADR 0625 section 4, issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -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.
|
// 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) {
|
func TestManifestAndModuleValuesKeepTheirRules(t *testing.T) {
|
||||||
if _, err := ManifestsKey("abc"); err == nil || !strings.Contains(err.Error(), `"abc"`) {
|
if _, err := ManifestsKey("abc"); err == nil || !strings.Contains(err.Error(), `"abc"`) {
|
||||||
t.Errorf("ManifestsKey(abc) = %v", err)
|
t.Errorf("ManifestsKey(abc) = %v", err)
|
||||||
|
|||||||
@@ -10,15 +10,6 @@ import (
|
|||||||
"git.novox.be/novox/mesh-sdk/go/keys"
|
"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.
|
// RootPath is a `modules` value's path when the module's manifest is its repository's root.
|
||||||
const RootPath = "."
|
const RootPath = "."
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,19 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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"
|
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
||||||
mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient"
|
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/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-delivery-builder/builds"
|
||||||
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
|
"git.novox.be/novox/mesh-delivery/modules/mesh-grants/grantsstate"
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/buildstep"
|
"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-server/v2/server"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
"github.com/nats-io/nats.go/jetstream"
|
"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"
|
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"
|
oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel"
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
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/catalogue"
|
||||||
"git.novox.be/novox/mesh-sdk/go/process"
|
"git.novox.be/novox/mesh-sdk/go/process"
|
||||||
"git.novox.be/novox/mesh-sdk/go/seatdef"
|
"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/go/seats/nodeengine"
|
||||||
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
|
"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
|
// 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).
|
// machineEvent; the grants part's own test holds the derivation).
|
||||||
if _, err := js.CreateOrUpdateConsumer(ctx, "EVENTS", jetstream.ConsumerConfig{Durable: "n1_mesh-delivery-assigner",
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// The operator-channel seat's stream of conditions, which the assigner says its conditions on.
|
// 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
|
firstViewBound, firstViewWait = 300*time.Millisecond, 50*time.Millisecond
|
||||||
t.Cleanup(func() { indexerLate, firstViewBound, firstViewWait = nil, 0, 0 })
|
t.Cleanup(func() { indexerLate, firstViewBound, firstViewWait = nil, 0, 0 })
|
||||||
for _, name := range append(append([]string{}, readBuckets...), watched...) {
|
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)
|
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"},
|
"seat-holders": {"n1.node-tools"},
|
||||||
"wants": {"n1.mesh-grants"},
|
"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 {
|
graphRaised := func() bool {
|
||||||
e, err := b.buckets[assign.FindingsBucket].Get(b.ctx, graphKey)
|
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) {
|
for deadline := time.Now().Add(10 * time.Second); !graphRaised(); time.Sleep(50 * time.Millisecond) {
|
||||||
if time.Now().After(deadline) {
|
if time.Now().After(deadline) {
|
||||||
@@ -1092,7 +1095,7 @@ func (s bedStore) kv(state string) jetstream.KeyValue {
|
|||||||
if strings.Contains(state, ".") {
|
if strings.Contains(state, ".") {
|
||||||
return s.b.buckets[strings.Replace(state, ".", "_", 1)]
|
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) {
|
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.
|
// and declined, writes nothing and is withdrawn.
|
||||||
func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) {
|
func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) {
|
||||||
b := startBed(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
|
Subjects: placementSubjects()}); err != nil { // the seat's four events: the views family has a stream of its own
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -1379,8 +1382,8 @@ func (b *bed) viewsHold(t *testing.T, state, key string) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for deadline := time.Now().Add(20 * time.Second); ; time.Sleep(50 * time.Millisecond) {
|
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) {
|
f := &views.Follower{Owner: placement.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())
|
return views.FirstView(placement.Module, state, src(kv), src(marks), "", time.Now())
|
||||||
}}
|
}}
|
||||||
if err := f.Start(b.ctx); err != nil {
|
if err := f.Start(b.ctx); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -1389,7 +1392,7 @@ func (b *bed) viewsHold(t *testing.T, state, key string) {
|
|||||||
gap := false
|
gap := false
|
||||||
for seq := info.State.FirstSeq; seq > 0 && seq <= info.State.LastSeq; seq++ {
|
for seq := info.State.FirstSeq; seq > 0 && seq <= info.State.LastSeq; seq++ {
|
||||||
m, err := st.GetMsg(b.ctx, 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
|
continue
|
||||||
}
|
}
|
||||||
e, err := views.DecodeEvent(m.Data)
|
e, err := views.DecodeEvent(m.Data)
|
||||||
@@ -1447,7 +1450,7 @@ func (s bedSource) Get(key string) (*views.Entry, bool, error) {
|
|||||||
func placementSubjects() []string {
|
func placementSubjects() []string {
|
||||||
var out []string
|
var out []string
|
||||||
for _, e := range mma.Events() {
|
for _, e := range mma.Events() {
|
||||||
out = append(out, process.ModuleStreamSubject(mmac.Module, e))
|
out = append(out, process.ModuleStreamSubject(placement.Module, e))
|
||||||
}
|
}
|
||||||
return out
|
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.
|
// 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) {
|
func serveIndexer(t *testing.T, b *bed, nc *nats.Conn) {
|
||||||
t.Helper()
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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}
|
Publish: views.JetStreamPublish(b.js), Marks: marks}
|
||||||
for state, bucket := range indexerFirstViews {
|
for state, bucket := range indexerFirstViews {
|
||||||
kv, err := b.js.CreateKeyValue(b.ctx, jetstream.KeyValueConfig{Bucket: bucket, History: 5})
|
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"`
|
After string `json:"after"`
|
||||||
}
|
}
|
||||||
_ = json.Unmarshal(m.Data, &args)
|
_ = 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"}
|
out := map[string]any{"result": a, "node": "n0"}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
out = map[string]any{"error": err.Error()}
|
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()
|
outR, outW := io.Pipe()
|
||||||
t.Cleanup(func() { inW.Close(); outW.Close() })
|
t.Cleanup(func() { inW.Close(); outW.Close() })
|
||||||
go func() {
|
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)
|
answers := make(chan map[string]any, 16)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -1571,7 +1574,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][]
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Cleanup(nc.Close)
|
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{}{}
|
one <- struct{}{}
|
||||||
defer func() { <-one }()
|
defer func() { <-one }()
|
||||||
tokens := strings.Split(msg.Subject, ".")
|
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) {
|
ask := func(user, tool string) (views.Answer, error) {
|
||||||
return views.AskVia(func(key string, body any) (json.RawMessage, error) {
|
return views.AskVia(func(key string, body any) (json.RawMessage, error) {
|
||||||
data, _ := json.Marshal(body)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
t.Errorf("%s's first view of %s before any new-form state: %v", user, tool, err)
|
||||||
case slices.Contains(allowed, user):
|
case slices.Contains(allowed, user):
|
||||||
keys, _ := b.buckets[viewedStates[tool]].Keys(b.ctx)
|
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)
|
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"):
|
case err == nil || !strings.Contains(err.Error(), "refused"):
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"mesh-delivery-assigner/internal/buckets"
|
"mesh-delivery-assigner/internal/buckets"
|
||||||
|
"mesh-delivery-assigner/internal/placement"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"slices"
|
"slices"
|
||||||
@@ -85,7 +85,7 @@ var ownBuckets = []string{buckets.Asks, buckets.Differences,
|
|||||||
const engineReadsState = "engine-reads"
|
const engineReadsState = "engine-reads"
|
||||||
|
|
||||||
// engineReadsBucket is that state's bucket.
|
// 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
|
// 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).
|
// 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).
|
// (ADR 0437 clause 9).
|
||||||
func sayVia(ctx context.Context, js jetstream.JetStream) func(oc.Condition) error {
|
func sayVia(ctx context.Context, js jetstream.JetStream) func(oc.Condition) error {
|
||||||
return func(c oc.Condition) error {
|
return func(c oc.Condition) error {
|
||||||
subject, err := occ.ConditionSubject(mmac.Module)
|
subject, err := occ.ConditionSubject(placement.Module)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// 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.
|
// 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)) {
|
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)
|
w := notHeardWriter(findings, logf)
|
||||||
handle := func(m jetstream.Msg) {
|
handle := func(m jetstream.Msg) {
|
||||||
if err := m.Ack(); err != nil {
|
if err := m.Ack(); err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"mesh-delivery-assigner/internal/buckets"
|
||||||
|
"mesh-delivery-assigner/internal/puts"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
||||||
wdc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshwatchdogsclient"
|
wdc "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshwatchdogsclient"
|
||||||
mwc "git.novox.be/novox/mesh-contracts/placement/go/clients/meshwantsclient"
|
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-assigner/asks"
|
||||||
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
|
"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/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"
|
"github.com/nats-io/nats.go/jetstream"
|
||||||
|
|
||||||
@@ -363,7 +364,7 @@ func putOfTheBus(t *testing.T) {
|
|||||||
buildKV.values[bkey] = built
|
buildKV.values[bkey] = built
|
||||||
modules := mem()
|
modules := mem()
|
||||||
modules.values["nats"] = mod
|
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 }
|
s.now = func() time.Time { return now }
|
||||||
was := answerWithin
|
was := answerWithin
|
||||||
answerWithin = 0
|
answerWithin = 0
|
||||||
@@ -1130,7 +1131,7 @@ func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
p.w.put(graph.Bucket, module, raw)
|
p.w.put(buckets.Graph, module, raw)
|
||||||
}
|
}
|
||||||
g := p.moduleGraph()
|
g := p.moduleGraph()
|
||||||
if got := keptInvokes(g, "caller"); !slices.Equal(got, []string{"seat:x.v"}) || keptInvokes(g, "unknown") != nil {
|
if got := keptInvokes(g, "caller"); !slices.Equal(got, []string{"seat:x.v"}) || keptInvokes(g, "unknown") != nil {
|
||||||
|
|||||||
@@ -5,19 +5,21 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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/clients/nodeengineclient"
|
||||||
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
||||||
mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient"
|
mdcc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliverycheckerclient"
|
||||||
mdc "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient"
|
mdc "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-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"
|
||||||
"github.com/nats-io/nats.go/jetstream"
|
"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 := nats.NewMsg(seatdef.EventSubject(mma.Seat, event))
|
||||||
msg.Header.Set("x-event-id", id)
|
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-node", node)
|
||||||
msg.Header.Set("x-time", time.Now().UTC().Format(time.RFC3339Nano))
|
msg.Header.Set("x-time", time.Now().UTC().Format(time.RFC3339Nano))
|
||||||
msg.Header.Set("content-type", "application/json")
|
msg.Header.Set("content-type", "application/json")
|
||||||
|
|||||||
@@ -4,14 +4,16 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
"mesh-delivery-assigner/internal/buckets"
|
||||||
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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"
|
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
||||||
mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
||||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
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'
|
// The states the verbs read, as the runtime names them: the seat's own by their local names, the others'
|
||||||
// `<module>.<state>`.
|
// `<module>.<state>`.
|
||||||
const (
|
const (
|
||||||
modulesState = meshcatalogclient.Module + ".modules"
|
modulesState = buckets.IndexerModule + ".modules"
|
||||||
haveState = "node-engine.have"
|
haveState = "node-engine.have"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
"mesh-delivery-assigner/internal/buckets"
|
||||||
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
|
|
||||||
"mesh-delivery-assigner/internal/puts"
|
"mesh-delivery-assigner/internal/puts"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -15,6 +14,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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"
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/enginereads"
|
"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))
|
v := strings.ToLower(strings.TrimSpace(version))
|
||||||
switch {
|
switch {
|
||||||
case v == "newest":
|
case v == "newest":
|
||||||
raw, _, found, err := s.st.get(meshcatalogclient.ModulesRead, module)
|
raw, _, found, err := s.st.get(buckets.ModulesRead, module)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("the indexer's modules cannot be read: %w", err)
|
return "", fmt.Errorf("the indexer's modules cannot be read: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"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"
|
"mesh-delivery-assigner/internal/buckets"
|
||||||
"slices"
|
"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-sdk/go/catalogue"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/graph"
|
"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.
|
// does not decode is left out, so its module waits on no verb.
|
||||||
func (p *passer) moduleGraph() graph.Graph {
|
func (p *passer) moduleGraph() graph.Graph {
|
||||||
g := 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)
|
module, err := graph.ParseKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"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/buckets"
|
||||||
|
"mesh-delivery-assigner/internal/placement"
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// marksBucket is the assigner's state of what its views family said each state up to.
|
// 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.
|
// viewedTool is one tool over one state of the assigner's.
|
||||||
type viewedTool struct{ tool, state, words string }
|
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)
|
marks := state(views.MarksState)
|
||||||
var out []stdio.Tool
|
var out []stdio.Tool
|
||||||
for _, t := range firstViewTools {
|
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 {
|
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.
|
// 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)} }
|
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 {
|
if findings.Put == nil {
|
||||||
return
|
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)
|
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
|
// 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.
|
// 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 {
|
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 {
|
if findings.Put != nil && findings.Delete != nil {
|
||||||
em.Findings = viewFindings(findings)
|
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).
|
// 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,
|
// 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;
|
// 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
|
// 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
|
// 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).
|
// 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
|
// 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
|
// 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 {
|
if iv.findings.Put == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f := views.UnansweredFinding(mmac.Module, s, time.Now())
|
f := views.UnansweredFinding(placement.Module, s, time.Now())
|
||||||
var err error
|
var err error
|
||||||
if raised {
|
if raised {
|
||||||
err = viewFindings(iv.findings).Put(f)
|
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
|
var all []*views.Follower
|
||||||
for state, bucket := range indexerFirstViews {
|
for state, bucket := range indexerFirstViews {
|
||||||
bucket := bucket
|
bucket := bucket
|
||||||
tool := meshcatalogclient.Module + "." + state
|
tool := buckets.IndexerModule + "." + state
|
||||||
f := &views.Follower{Owner: meshcatalogclient.Module, Tool: tool, State: state, Ask: views.AskVia(iv.call, tool), Logf: iv.logf,
|
f := &views.Follower{Owner: buckets.IndexerModule, Tool: tool, State: state, Ask: views.AskVia(iv.call, tool), Logf: iv.logf,
|
||||||
Bound: firstViewBound, Wait: firstViewWait,
|
Bound: firstViewBound, Wait: firstViewWait,
|
||||||
Raise: func(s views.Status) { finding(s, true) }, Clear: func(s views.Status) { finding(s, false) },
|
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) {
|
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
|
// 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.
|
// 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 {
|
_ = 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)
|
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
|
// 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.
|
// findings state it is said in the log alone.
|
||||||
func notHeardWriter(findings assign.Findings, logf func(string, ...any)) heard.Writer {
|
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 {
|
if findings.Delete != nil {
|
||||||
w.Delete = func(key string) error {
|
w.Delete = func(key string) error {
|
||||||
if keys, err := findings.Keys(); err == nil && !slices.Contains(keys, key) {
|
if keys, err := findings.Keys(); err == nil && !slices.Contains(keys, key) {
|
||||||
|
|||||||
@@ -4,17 +4,18 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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/buckets"
|
||||||
"mesh-delivery-assigner/internal/puts"
|
"mesh-delivery-assigner/internal/puts"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"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"
|
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"
|
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient"
|
||||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||||
@@ -32,7 +33,7 @@ import (
|
|||||||
// The states the verbs read, as the runtime names them.
|
// The states the verbs read, as the runtime names them.
|
||||||
const (
|
const (
|
||||||
policiesState = buckets.PoliciesState
|
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 is the seat's event of a person's policy set or taken back.
|
||||||
PolicyChangedEvent = "policy-changed"
|
PolicyChangedEvent = "policy-changed"
|
||||||
// busStepCause is the cause the bus's step is recorded under in the hand-act log.
|
// busStepCause is the cause the bus's step is recorded under in the hand-act log.
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ package assign
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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"
|
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/meshcatalogclient"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient"
|
"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-assigner/asks"
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient"
|
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"
|
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
|
// 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.
|
// data, whose restore ask waits for the operator.
|
||||||
func HeldCondition(module, fp, node, words string, raised, needsYou bool) oc.Condition {
|
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}
|
subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node}
|
||||||
if !raised {
|
if !raised {
|
||||||
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared}
|
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
|
// 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.
|
// (raised false) once the node no longer fails alone.
|
||||||
func NodeFailedCondition(node, module, fp string, f NodeFailure, raised bool) oc.Condition {
|
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}
|
subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node}
|
||||||
if !raised {
|
if !raised {
|
||||||
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared,
|
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
|
// 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.
|
// 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 {
|
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}
|
subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node}
|
||||||
if !raised {
|
if !raised {
|
||||||
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared,
|
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),
|
// 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.
|
// 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 {
|
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}
|
subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node}
|
||||||
if !raised {
|
if !raised {
|
||||||
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared}
|
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared}
|
||||||
|
|||||||
@@ -2,18 +2,19 @@ package assign
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
"mesh-delivery-assigner/internal/placement"
|
||||||
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/puts"
|
"mesh-delivery-assigner/internal/puts"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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"
|
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"
|
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"
|
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)
|
t.Fatalf("%s: %v", c.key, err)
|
||||||
}
|
}
|
||||||
got, ok := puts[c.key]
|
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 {
|
got.Subject.Machine != c.raised.Subject.Machine || said != 0 {
|
||||||
t.Fatalf("%s: finding %+v (written %v), said %d", c.key, got, puts, said)
|
t.Fatalf("%s: finding %+v (written %v), said %d", c.key, got, puts, said)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package assign
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
"mesh-delivery-assigner/internal/placement"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -21,13 +21,13 @@ import (
|
|||||||
// assigner no longer says it straight (never both).
|
// assigner no longer says it straight (never both).
|
||||||
|
|
||||||
// FindingsBucket is the assigner's findings.
|
// 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 `<scope>.<id>.<kind>`, from the condition's own key
|
// FindingOf is a said condition as a finding: its key `<scope>.<id>.<kind>`, from the condition's own key
|
||||||
// `mesh-delivery-assigner.<kind>.<id…>` (the subject's id when the key names none), its words unchanged. raised is false for
|
// `mesh-delivery-assigner.<kind>.<id…>` (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.
|
// 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) {
|
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 == "" {
|
if !ok || rest == "" {
|
||||||
return "", nil, false, fmt.Errorf("the condition %q is not the assigner's", c.Key)
|
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,
|
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,
|
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)
|
value, err = mcc.EncodeFinding(f)
|
||||||
return key, value, true, err
|
return key, value, true, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package assign
|
package assign
|
||||||
|
|
||||||
import (
|
import (
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
"mesh-delivery-assigner/internal/placement"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient"
|
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
|
// 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.
|
// §1): raised naming each, cleared when none is left.
|
||||||
func SeatWaitsCondition(unbound []string) oc.Condition {
|
func SeatWaitsCondition(unbound []string) oc.Condition {
|
||||||
key := mmac.Module + ".seat-states"
|
key := placement.Module + ".seat-states"
|
||||||
subject := oc.ConditionSubject{Scope: "module", ID: mmac.Module}
|
subject := oc.ConditionSubject{Scope: "module", ID: placement.Module}
|
||||||
if len(unbound) == 0 {
|
if len(unbound) == 0 {
|
||||||
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, Resolved: "the seat mesh-placement holds all its states."}
|
return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared, Resolved: "the seat mesh-placement holds all its states."}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package assign
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
|
||||||
"mesh-delivery-assigner/internal/buckets"
|
"mesh-delivery-assigner/internal/buckets"
|
||||||
|
"mesh-delivery-assigner/internal/placement"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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).
|
// 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`.
|
// 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.
|
// 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) {
|
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.
|
// 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) {
|
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 {
|
func also(provider, consumer string) []string {
|
||||||
|
|||||||
@@ -2,18 +2,20 @@ package assign
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshdeliveryclient"
|
|
||||||
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-assigner/asks"
|
|
||||||
"maps"
|
"maps"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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"
|
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"
|
oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel"
|
||||||
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
mmac "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
||||||
mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
mma "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
||||||
|
|
||||||
|
"mesh-delivery-assigner/internal/placement"
|
||||||
plc "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
|
// 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).
|
// module, or node and provision for a pin).
|
||||||
func CallClearedCondition(kind, node, module string) oc.Condition {
|
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,
|
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."}
|
Resolved: "the assigner calls no verb of the controller any more: placement is the one source."}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,16 @@ const (
|
|||||||
Have = "node-engine_" + nodeengine.StateHave
|
Have = "node-engine_" + nodeengine.StateHave
|
||||||
// ComposedRead is the family of the node-engine's composed states, one bucket per node.
|
// ComposedRead is the family of the node-engine's composed states, one bucket per node.
|
||||||
ComposedRead = "mesh-host." + nodeengine.StateComposed
|
ComposedRead = "mesh-host." + nodeengine.StateComposed
|
||||||
// Modules and Manifests are the indexer's.
|
// IndexerModule is the holder of the seat mesh-catalog, named from this module's manifest (`consumes` its views, `invokes`
|
||||||
Modules = "mesh-delivery-indexer_" + catalog.StateModules
|
// its tools; TestTheIndexerIsTheManifests), since no client names a holder (ADR 0625 §4).
|
||||||
Manifests = "mesh-delivery-indexer_" + catalog.StateManifests
|
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 holds each part's presence and the node's.
|
||||||
Presence = "mesh-delivery-watchman_" + watchdogs.StatePresence
|
Presence = "mesh-delivery-watchman_" + watchdogs.StatePresence
|
||||||
// Source and Merges are the gate's.
|
// Source and Merges are the gate's.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
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/contracts/go/seats/meshcatalog"
|
||||||
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/buildrun"
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/buildrun"
|
||||||
)
|
)
|
||||||
@@ -16,7 +15,7 @@ const (
|
|||||||
forgeBridgeModule = "mesh-delivery-forge-bridge"
|
forgeBridgeModule = "mesh-delivery-forge-bridge"
|
||||||
|
|
||||||
// indexerModule is the holder of the states modules, manifests, candidates and packages the builder follows.
|
// 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 is the holder of the state placement.
|
||||||
assignerModule = buildrun.AssignerModule
|
assignerModule = buildrun.AssignerModule
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package check
|
|||||||
import (
|
import (
|
||||||
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
"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-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/meshcatalog"
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdelivery"
|
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdelivery"
|
||||||
checker "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdeliverychecker"
|
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:
|
// IndexerModule holds the seat mesh-catalog's states, which the checker follows by their views (consumes:
|
||||||
// mesh-delivery-indexer.views.*).
|
// mesh-delivery-indexer.views.*).
|
||||||
IndexerModule = meshcatalogclient.Module
|
IndexerModule = "mesh-delivery-indexer"
|
||||||
CandidatesBucket = IndexerModule + "_" + meshcatalog.StateCandidates
|
CandidatesBucket = IndexerModule + "_" + meshcatalog.StateCandidates
|
||||||
ModulesBucket = IndexerModule + "_" + meshcatalog.StateModules
|
ModulesBucket = IndexerModule + "_" + meshcatalog.StateModules
|
||||||
ManifestsBucket = IndexerModule + "_" + meshcatalog.StateManifests
|
ManifestsBucket = IndexerModule + "_" + meshcatalog.StateManifests
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func TestIndexerWhole(t *testing.T) { // 1238/AC2, AC10; 1585/T14, T15
|
|||||||
}, func(ctx context.Context, js jetstream.JetStream) {
|
}, 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).
|
// 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,
|
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} {
|
index.SeatDefinitionsBucket: 1, index.RequirementsBucket: 1, findingsBucket: 1, index.HoldsBucket: 1} {
|
||||||
if _, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: bucket, History: history}); err != nil {
|
if _, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: bucket, History: history}); err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if _, ok := get(index.VerdictsBucket, own.Manifest); !ok {
|
||||||
t.Errorf("the verdict on the indexer's manifest %s is not written", own.Manifest)
|
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)
|
t.Errorf("the indexer's key %s of the module graph is not written", gk)
|
||||||
}
|
}
|
||||||
repoKey, _ := trunk.RepositoryKey(m1.Repository)
|
repoKey, _ := trunk.RepositoryKey(m1.Repository)
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import (
|
|||||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/enginereads"
|
"git.novox.be/novox/mesh-delivery/sdk/enginereads"
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/graph"
|
|
||||||
"git.novox.be/novox/mesh-sdk/go/process"
|
"git.novox.be/novox/mesh-sdk/go/process"
|
||||||
|
|
||||||
"mesh-delivery-indexer/internal/index"
|
"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.
|
// 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)
|
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.
|
// 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)
|
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.
|
// 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)
|
seatDefs := process.AwaitBucket(ctx, js, conn, index.SeatDefinitionsBucket, "no seat definition is kept", logger.Printf)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ type Indexer struct {
|
|||||||
ReadFile func(ctx context.Context, repository, sha, path string) ([]byte, error)
|
ReadFile func(ctx context.Context, repository, sha, path string) ([]byte, error)
|
||||||
// SaySeatDefinition says seat-definition-changed (seatdefs.go); nil says nothing.
|
// SaySeatDefinition says seat-definition-changed (seatdefs.go); nil says nothing.
|
||||||
SaySeatDefinition func(ctx context.Context, c SeatDefinitionChanged) error
|
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
|
Graph Store
|
||||||
// Files asks the forge for every blob under each directory at a commit, by directory then path relative to it, each
|
// 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.
|
// with its git object id (gitea.gitea_commit_trees with files): the listing a package's digest is computed from.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// The module graph (novox/hq ADR 0603 §2): at every recompute the indexer writes, in its state graph
|
// 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
|
// 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
|
// 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).
|
// mesh-catalog's verbs read it; nothing stores an order (ADR 0603 §1).
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package index
|
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
|
// 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
|
// `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).
|
// (TestTheNamesAreTheManifests). No contract names a holder (novox/hq ADR 0625 §4, ADR 0634 §1).
|
||||||
const (
|
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"
|
Module = "mesh-delivery-indexer"
|
||||||
|
|
||||||
// The indexer's own states, with the revisions each keeps per key (module.json `state`).
|
// The indexer's own states, with the revisions each keeps per key (module.json `state`).
|
||||||
@@ -17,6 +19,8 @@ const (
|
|||||||
ManifestsState = "manifests"
|
ManifestsState = "manifests"
|
||||||
ManifestsBucket = Module + "_" + ManifestsState
|
ManifestsBucket = Module + "_" + ManifestsState
|
||||||
ManifestsHistory = 1
|
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.
|
// VerdictsState and VerdictsBucket are in verdicts.go.
|
||||||
VerdictsHistory = 5
|
VerdictsHistory = 5
|
||||||
PredefinedState = "predefined"
|
PredefinedState = "predefined"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ var ViewedStates = map[string]string{
|
|||||||
ConfigCandidatesState: ConfigCandidatesBucket,
|
ConfigCandidatesState: ConfigCandidatesBucket,
|
||||||
"candidates": CandidatesBucket,
|
"candidates": CandidatesBucket,
|
||||||
PackagesState: PackagesBucket,
|
PackagesState: PackagesBucket,
|
||||||
graph.State: graph.Bucket,
|
graph.State: GraphBucket,
|
||||||
HeardState: HeardBucket,
|
HeardState: HeardBucket,
|
||||||
"taken": TakenBucket,
|
"taken": TakenBucket,
|
||||||
mcc.FindingsState: mcc.FindingsBucket(Module),
|
mcc.FindingsState: mcc.FindingsBucket(Module),
|
||||||
|
|||||||
@@ -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)
|
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,
|
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 }) {
|
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)
|
t.Errorf("the indexer names its bucket %s with %d revisions, its manifest's states are %+v", bucket, history, m.State)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package view
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"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/contracts/go/seats/meshcatalog"
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/trunk"
|
"git.novox.be/novox/mesh-delivery/sdk/trunk"
|
||||||
"git.novox.be/novox/mesh-sdk/go/keys"
|
"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
|
// `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.
|
// ADR 0625 §4, ADR 0634 §1). The indexer's module and its reads are the catalog client's.
|
||||||
const (
|
const (
|
||||||
IndexerModule = meshcatalogclient.Module
|
IndexerModule = "mesh-delivery-indexer"
|
||||||
AssignerModule = "mesh-delivery-assigner"
|
AssignerModule = "mesh-delivery-assigner"
|
||||||
WatchmanModule = "mesh-delivery-watchman"
|
WatchmanModule = "mesh-delivery-watchman"
|
||||||
GateModule = "mesh-delivery-gate"
|
GateModule = "mesh-delivery-gate"
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ accounts {
|
|||||||
func serveOwners(t *testing.T, ctx context.Context, js jetstream.JetStream, nc *nats.Conn) {
|
func serveOwners(t *testing.T, ctx context.Context, js jetstream.JetStream, nc *nats.Conn) {
|
||||||
t.Helper()
|
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, 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)
|
// TestWatchmanWhole starts the program the way the node does (its entry, run, with its environment and a broker file)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
sdkfindings "git.novox.be/novox/mesh-delivery/sdk/findings"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -19,6 +18,8 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"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/process"
|
||||||
"git.novox.be/novox/mesh-sdk/go/views"
|
"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/health-and-repair/go/clients/meshwatchdogsclient"
|
||||||
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient"
|
"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/modules/mesh-delivery-indexer/takein"
|
||||||
"git.novox.be/novox/mesh-delivery/sdk/buildstep"
|
"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 {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -455,7 +455,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
|||||||
w.TakeInCaughtUp()
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,7 +535,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
|
|||||||
const eventsStream = "EVENTS"
|
const eventsStream = "EVENTS"
|
||||||
|
|
||||||
// pendingTool is the indexer's tool that answers the waits it holds (ADR 0633 §5), as the view asks it.
|
// 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
|
// 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.
|
// answer is said: the waits are then known only from the events heard after.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package watch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
meshwatchdogs "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshwatchdogs"
|
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
|
// 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 (
|
const (
|
||||||
WatchmanModule = "mesh-delivery-watchman"
|
WatchmanModule = "mesh-delivery-watchman"
|
||||||
AssignerModule = "mesh-delivery-assigner"
|
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.
|
// The watchman's own states of the seat mesh-watchdogs.
|
||||||
PresenceBucket = WatchmanModule + "_" + meshwatchdogs.StatePresence
|
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 is the assigner's state wants, followed by its views family (consumes: mesh-delivery-assigner.views.wants).
|
||||||
AssignerWantsBucket = AssignerModule + "_wants"
|
AssignerWantsBucket = AssignerModule + "_wants"
|
||||||
// ModulesBucket is the indexer's state modules, followed by its views family (consumes: mesh-delivery-indexer.views.modules).
|
// 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.
|
// The findings a value of another part is raised as, named by their words.
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
|
||||||
|
|
||||||
"mesh-delivery-watchman/internal/watch"
|
"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")},
|
"wants": {watch.AssignerWantsBucket, bucket(m.Consumes, "mesh-delivery-assigner.views.wants")},
|
||||||
"modules": {watch.ModulesBucket, bucket(m.Consumes, "mesh-delivery-indexer.views.modules")},
|
"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")},
|
"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 {
|
if row.got != row.want {
|
||||||
t.Errorf("the name for %s is %q, its manifest's is %q", name, row.got, row.want)
|
t.Errorf("the name for %s is %q, its manifest's is %q", name, row.got, row.want)
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ package buscompose
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"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"
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -14,9 +11,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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/clients/meshvaultclient"
|
||||||
"git.novox.be/novox/mesh-contracts/identity-and-access/go/seats/meshvault"
|
"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-delivery/modules/mesh-delivery-builder/builds"
|
||||||
"git.novox.be/novox/mesh-sdk/go/announce"
|
"git.novox.be/novox/mesh-sdk/go/announce"
|
||||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
"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
|
// 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.
|
// proposal laid over), and none of its open proposals; it writes neither.
|
||||||
reads := strings.Join(NodeComposeReads("laptop"), " ")
|
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} {
|
PlacementProposalsBucket: false} {
|
||||||
if strings.Contains(reads, "$JS.API.DIRECT.GET.KV_"+bucket+".>") != granted || strings.Contains(reads, "$KV."+bucket+".laptop") {
|
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)
|
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},
|
{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.
|
// 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"}}},
|
{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)}},
|
{Module: AssignerModule, State: []Bucket{bucket(AssignerModule, meshmoduleassigner.StateSeatHolders)}},
|
||||||
// ADR 0571 clause 3: disk-load keeps the readings; the backup holder reads them.
|
// 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.
|
// ADR 0577 clause 1: and it reads its own node's keys of the node-engine's data items, which restic may not.
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ const (
|
|||||||
// EnrolmentModule is the module holding the seat mesh-node-enroller.
|
// EnrolmentModule is the module holding the seat mesh-node-enroller.
|
||||||
EnrolmentModule = "mesh-enrolment"
|
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"
|
AssignerWantsBucket = AssignerModule + "_wants"
|
||||||
PlacementCandidatesBucket = AssignerModule + "_candidates"
|
PlacementCandidatesBucket = AssignerModule + "_candidates"
|
||||||
PlacementProposalsBucket = AssignerModule + "_placement-proposals"
|
PlacementProposalsBucket = AssignerModule + "_placement-proposals"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ func namesAreTheManifests(t *testing.T) {
|
|||||||
{"reads", HaveBucket[:strings.Index(HaveBucket, "_")] + ".have", HaveBucket},
|
{"reads", HaveBucket[:strings.Index(HaveBucket, "_")] + ".have", HaveBucket},
|
||||||
{"reads", NodeLoginsRead, NodeLoginsBucket},
|
{"reads", NodeLoginsRead, NodeLoginsBucket},
|
||||||
{"reads", EnrolmentsRead, EnrolmentsBucket},
|
{"reads", EnrolmentsRead, EnrolmentsBucket},
|
||||||
|
{"invokes", PlacementRead, PlacementBucket},
|
||||||
{"invokes", AssignerModule + ".wants", AssignerWantsBucket},
|
{"invokes", AssignerModule + ".wants", AssignerWantsBucket},
|
||||||
{"invokes", IndexerModule + ".modules", ModulesBucket},
|
{"invokes", IndexerModule + ".modules", ModulesBucket},
|
||||||
{"invokes", IndexerModule + ".manifests", ManifestsBucket},
|
{"invokes", IndexerModule + ".manifests", ManifestsBucket},
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
|
||||||
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient"
|
"git.novox.be/novox/mesh-contracts/provisioning/go/clients/meshprovisionerclient"
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
"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
|
// 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
|
// 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.
|
// 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
|
// 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, `<node>.<module>.<provision>[.<local>]`, to fill
|
// consumer's machine's client reads its own keys of it, `<node>.<module>.<provision>[.<local>]`, to fill
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package buscompose
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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).
|
// 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.
|
// secret. Reads only; the node is checked as every subject token is by the caller's principal.
|
||||||
func NodeComposeReads(node string) []string {
|
func NodeComposeReads(node string) []string {
|
||||||
var out []string
|
var out []string
|
||||||
for _, bucket := range []string{meshmoduleassignerclient.PlacementBucket, PlacementCandidatesBucket, ModulesBucket,
|
for _, bucket := range []string{PlacementBucket, PlacementCandidatesBucket, ModulesBucket,
|
||||||
ManifestsBucket, builds.BuilderBuildsBucket} {
|
ManifestsBucket, builds.BuilderBuildsBucket} {
|
||||||
out = append(out, readGrants(bucket, "")...)
|
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
|
// 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.
|
// (ADR 0567 §9): what a node agent hears to bind each once it is made. Those two and no wider.
|
||||||
func NodeComposeAdvisories() []string {
|
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, `<node>.<module>.<key>`
|
// ServedReadGrants is the read of each key of mesh-config's resolved values named, `<node>.<module>.<key>`
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"mesh-grants/internal/buscompose"
|
||||||
|
|
||||||
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
"git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
||||||
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
"git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
||||||
"git.novox.be/novox/mesh-contracts/identity-and-access/go/clients/meshvaultclient"
|
"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-delivery/modules/mesh-delivery-builder/builds"
|
||||||
"git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay"
|
"git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay"
|
||||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
"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 (`<module>.<state>`).
|
// The states of other parts the grants part reads, as its manifest's reads name them (`<module>.<state>`).
|
||||||
@@ -48,7 +49,7 @@ const (
|
|||||||
ReadAccounts = "mesh-vault.bus-accounts"
|
ReadAccounts = "mesh-vault.bus-accounts"
|
||||||
// ReadPlacement is the seat mesh-placement's placement (ADR 0567 §1, §9): each node's modules and the seats
|
// ReadPlacement is the seat mesh-placement's placement (ADR 0567 §1, §9): each node's modules and the seats
|
||||||
// they hold.
|
// 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
|
// 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.<node>.
|
// live or redeeming composes the user enrol.<node>.
|
||||||
ReadEnrolments = buscompose.EnrolmentsRead
|
ReadEnrolments = buscompose.EnrolmentsRead
|
||||||
|
|||||||
+4
-6
@@ -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.
|
// operator, 2026-11-03: no graph-related code in mesh-sdk, only contracts). It names no module.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// State is the name of the indexer's state of the module graph, as its manifest declares it, and Bucket its
|
// State is the name of the indexer's state of the module graph, as its manifest declares it: one key per module
|
||||||
// bucket: one key per module (Key).
|
// (Key). Its bucket is the holder's name and the state's, which the indexer and each reader name from its own
|
||||||
State = "graph"
|
// manifest, never this package (ADR 0625 §4).
|
||||||
Bucket = meshcatalogclient.Module + "_" + State
|
State = "graph"
|
||||||
// Read is the line a reader's manifest names in `reads` to read the graph.
|
|
||||||
Read = meshcatalogclient.Module + "." + State
|
|
||||||
// History is the revisions the graph state keeps per key (ADR 0603 §2).
|
// History is the revisions the graph state keeps per key (ADR 0603 §2).
|
||||||
History = 5
|
History = 5
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
|
// 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).
|
// refused naming why, and the state is the indexer's graph (ADR 0603 §2).
|
||||||
func nodeValues(t *testing.T) {
|
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")
|
t.Error("the graph's state differs from the decided layout")
|
||||||
}
|
}
|
||||||
g := sampleNode()
|
g := sampleNode()
|
||||||
|
|||||||
Reference in New Issue
Block a user