From b2bddecde2ee93349d14ec3ef603cc5df144d66b Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 13 Nov 2026 20:37:25 +0100 Subject: [PATCH] S3: the indexer takes its own build from MESH_FINGERPRINT first Builds: design 47 G A-366 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- .../cmd/mesh-delivery-indexer/main.go | 2 +- .../cmd/mesh-delivery-indexer/named_test.go | 20 +++++++++++++++++++ .../cmd/mesh-delivery-indexer/ownbuild.go | 13 ++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go index f1aa923e..15bcb241 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/main.go @@ -462,7 +462,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro Predefined: awaitedStore{b: predefined}, ConfigCandidates: awaitedStore{b: configCandidates}, Logf: logger.Printf, Named: namedVia(calls.Call), Trunk: trunkVia(calls.Call), Contains: containsVia(calls.Call), Read: readVia(calls.Call), ReadOpen: openVia(calls.Call), Packages: awaitedStore{b: packages, js: js, name: index.Bucket(cred.Module, index.PackagesState)}, Files: filesVia(calls.Call), GoSum: goSumVia(calls.Call), GoMod: goModVia(calls.Call), - OwnBuild: ownBuildVia(calls.Call, cred.Module, cred.Node), OwnBuildState: awaitedStore{b: ownBuildState}, Heard: heardStore, Placement: placementVia(calls.CallKept), RunningWhole: runningWholeVia(js), Runs: awaitedStore{b: runs}, Graph: graph, + OwnBuild: ownBuildFirst(process.OwnBuild(), ownBuildVia(calls.Call, cred.Module, cred.Node)), OwnBuildState: awaitedStore{b: ownBuildState}, Heard: heardStore, Placement: placementVia(calls.CallKept), RunningWhole: runningWholeVia(js), Runs: awaitedStore{b: runs}, Graph: graph, SeatDefinitions: awaitedStore{b: seatDefs}, ReadFile: readFileVia(calls.Call), SaySeatDefinition: saySeats, Revisions: revisions, EntryIndex: awaitedStore{b: process.AwaitBucket(ctx, js, conn, index.Bucket(cred.Module, index.EntryIndexState), "no entry is found by its fingerprint", logger.Printf)}, // Message a kept call: a read, called again through a transport fault (ADR 0668 ยง1) // Each catalog revision may bring another holder of a build seat: the build modules are found again (buildmodules.go). diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/named_test.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/named_test.go index e0ca9587..80eed033 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/named_test.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/named_test.go @@ -7,6 +7,7 @@ import ( "fmt" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/git" "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshpipelinerunner" + "git.novox.be/novox/mesh-sdk/go/process" "mesh-delivery-indexer/internal/index" "slices" "strings" @@ -125,6 +126,25 @@ func TestTheTrunkIsTheDirectoriesTheForgeListsTrees(t *testing.T) { // 1900/AC3 t.Errorf("%s: own build = %q %v, want %q", row.name, fp, err, row.want) } } + // Design 47 G A-366: a process started with a fingerprint takes it and asks no engine; one started without asks the engine. + for _, row := range []struct { + name string + started process.Build + want string + wantAsked bool + }{ + {"started with a fingerprint", process.Build{Fingerprint: "src2:env"}, "src2:env", false}, + {"started without one", process.Build{Unknown: process.OwnBuildUnknown}, "src2:abc", true}, + } { + called := false + ask := func(string, any) (json.RawMessage, error) { + called = true + return json.RawMessage(`{"runs":{"fp":"src2:abc"}}`), nil + } + if fp, err := ownBuildFirst(row.started, ownBuildVia(ask, "acme-indexer", "n1"))(context.Background()); err != nil || fp != row.want || called != row.wantAsked { + t.Errorf("%s: own build = %q %v, engine asked %v, want %q asked %v", row.name, fp, err, called, row.want, row.wantAsked) + } + } none := func(string, any) (json.RawMessage, error) { return json.RawMessage(`{}`), nil } if _, err := ownBuildVia(none, "acme-indexer", "n1")(context.Background()); err == nil { t.Error("an engine that says nothing runs gave a build") diff --git a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/ownbuild.go b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/ownbuild.go index 6d74a199..dda2099a 100644 --- a/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/ownbuild.go +++ b/modules/mesh-delivery-indexer/cmd/mesh-delivery-indexer/ownbuild.go @@ -5,6 +5,8 @@ import ( "encoding/json" "errors" "fmt" + + "git.novox.be/novox/mesh-sdk/go/process" ) // compositionVerb is the node-engine seat's read verb that says what runs of a module on a machine (its Runs.FP), asked of @@ -12,6 +14,17 @@ import ( // from the trunk's value of itself or the haves bucket. const compositionVerb = "seat:node-engine.composition" +// ownBuildFirst is the build the process was started with (mesh-sdk process.OwnBuild: MESH_FINGERPRINT, set by the node-engine +// and by a unit started by hand); only when it is unset does it ask the engine through ask (design 47 G A-366). +func ownBuildFirst(started process.Build, ask func(ctx context.Context) (string, error)) func(ctx context.Context) (string, error) { + return func(ctx context.Context) (string, error) { + if started.Fingerprint != "" { + return started.Fingerprint, nil + } + return ask(ctx) + } +} + // ownBuildVia asks the engine of node which fingerprint of the indexer runs there. func ownBuildVia(call toolCaller, module, node string) func(ctx context.Context) (string, error) { return func(context.Context) (string, error) {