CAT-RD1..RD10: the readers use mesh-sdk's views.Reader, say an unanswered first view in their own findings (mesh-conditions observes them) and record a re-read through mesh-hand-acts
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
|
||||
"artifactstoretools/internal/registry"
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
|
||||
"artifactstoretools/internal/registry"
|
||||
)
|
||||
|
||||
@@ -11,7 +11,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
@@ -20,7 +19,7 @@ import (
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, format+"\n", a...) }
|
||||
@@ -31,7 +30,7 @@ func main() {
|
||||
Run: ExecRunner,
|
||||
UID: os.Getuid(),
|
||||
}
|
||||
v := &views.Reader{Module: "artifact-store-tools", Logf: logf, Findings: viewFindings{}}
|
||||
v := &views.Reader{Module: "artifact-store-tools", Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}}
|
||||
v.Follow(delivery.AssignerModule, "wants", WantsTool)
|
||||
v.Follow(delivery.IndexerModule, "manifests", ManifestsTool)
|
||||
h := &Holder{Bus: runtimeBus{views: v}, Door: DoorAt(os.Getenv("MESH_ARTIFACT_STORE_ADDRESS_FILE")), Listed: s.View,
|
||||
@@ -51,12 +50,3 @@ const (
|
||||
WantsTool = delivery.AssignerModule + ".assigner_read_wants"
|
||||
ManifestsTool = delivery.IndexerModule + ".indexer_read_manifests"
|
||||
)
|
||||
|
||||
// viewFindings writes the holder's finding of a first view unanswered into its own state findings.
|
||||
type viewFindings struct{}
|
||||
|
||||
func (viewFindings) Put(key string, value []byte) error {
|
||||
_, err := stdio.State(FindingsState).Put(key, json.RawMessage(value))
|
||||
return err
|
||||
}
|
||||
func (viewFindings) Delete(key string) error { return stdio.State(FindingsState).Delete(key) }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
@@ -562,7 +562,8 @@
|
||||
],
|
||||
"state": [
|
||||
"bound",
|
||||
"announced"
|
||||
"announced",
|
||||
"findings"
|
||||
],
|
||||
"reads": [
|
||||
"mesh-provisioner.plans",
|
||||
@@ -575,7 +576,8 @@
|
||||
"mesh-delivery-gate.source"
|
||||
],
|
||||
"invokes": [
|
||||
"mesh-delivery-indexer.indexer_read_modules"
|
||||
"mesh-delivery-indexer.indexer_read_modules",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-delivery-indexer.views.modules"
|
||||
|
||||
@@ -15,6 +15,8 @@ var Kept = []announce.State{
|
||||
{Name: "keys", Readable: true},
|
||||
{Name: "steps", Readable: true},
|
||||
{Name: "pauses", Readable: true},
|
||||
// The condition keeper raises a first view of the indexer's manifests it could not get (ADR 0615 §6) from this.
|
||||
{Name: "findings", Readable: true},
|
||||
}
|
||||
|
||||
// keepStates announces Kept as this module's (stdio.Keeps): main calls it before it serves.
|
||||
|
||||
@@ -22,12 +22,14 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep"
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
sdkstep "git.novox.be/novox/mesh-sdk/go/buildstep"
|
||||
"git.novox.be/novox/mesh-sdk/go/composer"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
// ManifestsTool is the delivery indexer's read tool of its manifests by digest, which a compose ask's request names (the
|
||||
@@ -71,12 +73,28 @@ func (m *Module) compose(ctx context.Context, fetch buildstep.StepFunc, a delive
|
||||
return delivery.ComposeAnswer{Built: built, Key: key, Verdict: verdict}, nil
|
||||
}
|
||||
|
||||
// askManifest asks the indexer's read tool for one manifest by its key: nil when it keeps none.
|
||||
// askManifest asks the indexer's read tool for one manifest by its key: nil when it keeps none. A call the indexer does not
|
||||
// answer is a finding of this module's own, which the condition keeper raises (ADR 0615 §6) and the next answer clears.
|
||||
func askManifest(key string) (json.RawMessage, error) {
|
||||
raw, err := stdio.Ask(ManifestsTool, map[string]any{"key": key})
|
||||
return askManifestVia(stdio.Ask, views.OwnFindings{}, time.Now, key)
|
||||
}
|
||||
|
||||
func askManifestVia(ask func(string, any) (json.RawMessage, error), findings interface {
|
||||
Put(string, []byte) error
|
||||
Delete(string) error
|
||||
}, now func() time.Time, key string) (json.RawMessage, error) {
|
||||
st := views.Status{Owner: delivery.IndexerModule, Tool: ManifestsTool, State: "manifests", Asked: now().UTC()}
|
||||
raw, err := ask(ManifestsTool, map[string]any{"key": key})
|
||||
if err != nil {
|
||||
st.Error = err.Error()
|
||||
if k, v, ferr := views.UnansweredFinding("mesh-build-go", st, now()); ferr == nil {
|
||||
_ = findings.Put(k, v)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if k, _, ferr := views.UnansweredFinding("mesh-build-go", st, now()); ferr == nil {
|
||||
_ = findings.Delete(k)
|
||||
}
|
||||
var a struct {
|
||||
Found bool `json:"found"`
|
||||
Value json.RawMessage `json:"value"`
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
@@ -130,6 +131,27 @@ func TestTheModuleReadsTheIndexersManifests(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ADR 0615 §6: an indexer that does not answer is a finding of the module's own, and its next answer clears it.
|
||||
func TestAnIndexerThatDoesNotAnswerIsAFinding(t *testing.T) {
|
||||
held := map[string][]byte{}
|
||||
f := mapFindings(held)
|
||||
at := func() time.Time { return time.Date(2026, 11, 4, 12, 0, 0, 0, time.UTC) }
|
||||
if _, err := askManifestVia(func(string, any) (json.RawMessage, error) { return nil, errors.New("no responders") }, f, at, "k"); err == nil || len(held) != 1 {
|
||||
t.Fatalf("err %v, findings %v", err, held)
|
||||
}
|
||||
raw, err := askManifestVia(func(string, any) (json.RawMessage, error) {
|
||||
return json.RawMessage(`{"found":true,"value":{"x":1}}`), nil
|
||||
}, f, at, "k")
|
||||
if err != nil || string(raw) != `{"x":1}` || len(held) != 0 {
|
||||
t.Errorf("raw %s, err %v, findings %v", raw, err, held)
|
||||
}
|
||||
}
|
||||
|
||||
type mapFindings map[string][]byte
|
||||
|
||||
func (m mapFindings) Put(k string, v []byte) error { m[k] = v; return nil }
|
||||
func (m mapFindings) Delete(k string) error { delete(m, k); return nil }
|
||||
|
||||
// ADR 0593 §7 (C9): a compose ask naming the node-engine's repository builds its composer command in the Go module at the
|
||||
// repository's root, under a key of that repository, commit and package, and runs the program over the request with its
|
||||
// manifests filled; the module's answer is the program's verdict whole.
|
||||
|
||||
@@ -106,7 +106,7 @@ func TestManifestKeepsItsStatesClaimsItsBuildSeatAndDeclaresItsHealthTool(t *tes
|
||||
}
|
||||
}
|
||||
slices.Sort(states)
|
||||
if want := []string{"keys", "pauses", "steps", "toolchains"}; !slices.Equal(states, want) {
|
||||
if want := []string{"findings", "keys", "pauses", "steps", "toolchains"}; !slices.Equal(states, want) {
|
||||
t.Errorf("state = %v, want %v", states, want)
|
||||
}
|
||||
if len(m.Claims) != 1 || m.Claims[0].Name != Seat {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"state": [
|
||||
"toolchains",
|
||||
"keys",
|
||||
{"name": "steps", "ttl-seconds": 172800}, "pauses"
|
||||
{"name": "steps", "ttl-seconds": 172800}, "pauses", "findings"
|
||||
],
|
||||
"claims": [
|
||||
{
|
||||
|
||||
@@ -40,7 +40,10 @@ const HistoryKeptFor = 90 * 24 * time.Hour
|
||||
// table of 2026-10-29 for the provisioner's and the router's; ADR 0571 clause 2 for the seat artifact-store's holder,
|
||||
// which observes S25, image-missing).
|
||||
var Observers = []string{health.WatchmanModule, health.SelfCheckModule, health.HealersModule, delivery.AssignerModule,
|
||||
"mesh-provisioner", "messenger", artifactStore, configModule}
|
||||
"mesh-provisioner", "messenger", artifactStore, configModule,
|
||||
// The readers of the indexer's and the assigner's state say a first view unanswered past its bound in their own findings
|
||||
// (ADR 0615 §6).
|
||||
"mesh-watcher", "minio", "nfs-server", "gitea", "mesh-build-go"}
|
||||
|
||||
// The other states it reads, as `<module>.<name>`.
|
||||
const (
|
||||
|
||||
@@ -17,7 +17,8 @@ import (
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, format+"\n", a...) }
|
||||
@@ -147,7 +148,7 @@ const (
|
||||
// NewViews is the keeper's pictures of the assigner's wants, placement and findings. A first view it cannot get past its
|
||||
// bound is a finding of its own, taken in as any observer's: the keeper raises the condition itself.
|
||||
func NewViews(k *Keeper) *views.Reader {
|
||||
v := &views.Reader{Module: Module, Logf: logf, Findings: ownFindings{k}}
|
||||
v := &views.Reader{Module: Module, Logf: logf, Findings: ownFindings{k}, Acts: handacts.Recorder{Ask: stdio.Ask}}
|
||||
v.Follow(delivery.AssignerModule, "wants", WantsTool)
|
||||
v.Follow(delivery.AssignerModule, "placement", PlacementTool)
|
||||
v.Follow(delivery.AssignerModule, health.FindingsState, FindingsTool)
|
||||
|
||||
@@ -38,7 +38,7 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
|
||||
reads = append(reads, o+"."+health.FindingsState)
|
||||
}
|
||||
}
|
||||
if !slices.Equal(m.Invokes, []string{WantsTool, PlacementTool, FindingsTool}) ||
|
||||
if !slices.Equal(m.Invokes, []string{WantsTool, PlacementTool, FindingsTool, "seat:mesh-hand-acts.hand-act"}) ||
|
||||
!slices.Equal(m.Consumes, []string{"mesh-delivery-assigner.views.wants", "mesh-delivery-assigner.views.placement", "mesh-delivery-assigner.views.findings"}) {
|
||||
t.Errorf("invokes %v, consumes %v", m.Invokes, m.Consumes)
|
||||
}
|
||||
|
||||
@@ -21,13 +21,19 @@
|
||||
"mesh-provisioner.findings",
|
||||
"artifact-store-tools.findings",
|
||||
"mesh-config.findings",
|
||||
"mesh-watcher.findings",
|
||||
"minio.findings",
|
||||
"nfs-server.findings",
|
||||
"gitea.findings",
|
||||
"mesh-build-go.findings",
|
||||
"mesh-healers.attempts",
|
||||
"node-engine.have"
|
||||
],
|
||||
"invokes": [
|
||||
"mesh-delivery-assigner.assigner_read_wants",
|
||||
"mesh-delivery-assigner.assigner_read_placement",
|
||||
"mesh-delivery-assigner.assigner_read_findings"
|
||||
"mesh-delivery-assigner.assigner_read_findings",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-delivery-assigner.views.wants",
|
||||
|
||||
@@ -8,7 +8,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -19,9 +18,9 @@ import (
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/asks"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
// Seat is the role this module holds, once for the mesh, and Verb its one verb.
|
||||
@@ -182,20 +181,10 @@ const (
|
||||
ManifestsTool = delivery.IndexerModule + ".indexer_read_manifests"
|
||||
)
|
||||
|
||||
// viewFindings writes the provisioner's finding of a first view unanswered into its own state findings, which the
|
||||
// condition keeper raises the condition from.
|
||||
type viewFindings struct{}
|
||||
|
||||
func (viewFindings) Put(key string, value []byte) error {
|
||||
_, err := stdio.State(health.FindingsState).Put(key, json.RawMessage(value))
|
||||
return err
|
||||
}
|
||||
func (viewFindings) Delete(key string) error { return stdio.State(health.FindingsState).Delete(key) }
|
||||
|
||||
// newViews is the provisioner's pictures of the assigner's placement and wants and the indexer's modules and manifests:
|
||||
// each asked once of its owner's read tool, then followed by the owner's events (ADR 0615).
|
||||
func newViews() *views.Reader {
|
||||
v := &views.Reader{Module: Module, Logf: logf, Findings: viewFindings{}}
|
||||
v := &views.Reader{Module: Module, Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}}
|
||||
v.Follow(delivery.AssignerModule, "placement", PlacementTool)
|
||||
v.Follow(delivery.AssignerModule, "wants", WantsTool)
|
||||
v.Follow(delivery.IndexerModule, "modules", ModulesTool)
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
// memStore is the bus as mesh-provisioner reaches it, in memory: the states it keeps.
|
||||
@@ -345,7 +345,7 @@ func TestTheManifestDeclaresWhatTheCodeKeeps(t *testing.T) {
|
||||
t.Errorf("the manifest does not read %s, which the holder reads", r)
|
||||
}
|
||||
}
|
||||
if !slices.Equal(m.Invokes, []string{PlacementTool, WantsTool, ModulesTool, ManifestsTool}) ||
|
||||
if !slices.Equal(m.Invokes, []string{PlacementTool, WantsTool, ModulesTool, ManifestsTool, "seat:mesh-hand-acts.hand-act"}) ||
|
||||
!slices.Equal(m.Consumes, []string{"mesh-delivery-assigner.views.placement", "mesh-delivery-assigner.views.wants",
|
||||
"mesh-delivery-indexer.views.modules", "mesh-delivery-indexer.views.manifests"}) {
|
||||
t.Errorf("invokes %v, consumes %v", m.Invokes, m.Consumes)
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
"mesh-delivery-assigner.assigner_read_placement",
|
||||
"mesh-delivery-assigner.assigner_read_wants",
|
||||
"mesh-delivery-indexer.indexer_read_modules",
|
||||
"mesh-delivery-indexer.indexer_read_manifests"
|
||||
"mesh-delivery-indexer.indexer_read_manifests",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-delivery-assigner.views.placement",
|
||||
|
||||
@@ -15,7 +15,8 @@ import (
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, format+"\n", a...) }
|
||||
@@ -73,7 +74,7 @@ func NewChecker() *Checker {
|
||||
// its owner's read tool, then followed by the owner's events. A first view unanswered past its bound is a finding of the
|
||||
// self-check's own (first-view-unanswered), written into its state findings.
|
||||
func newViews() *views.Reader {
|
||||
r := &views.Reader{Module: Module, Logf: logf, Findings: findings{}}
|
||||
r := &views.Reader{Module: Module, Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}}
|
||||
r.Follow(delivery.AssignerModule, delivery.PlacementState, PlacementTool)
|
||||
r.Follow(delivery.AssignerModule, delivery.SeatHoldersState, SeatHoldersTool)
|
||||
r.Follow(delivery.IndexerModule, "modules", ModulesTool)
|
||||
@@ -81,15 +82,6 @@ func newViews() *views.Reader {
|
||||
return r
|
||||
}
|
||||
|
||||
// findings writes the self-check's own state findings for the reader.
|
||||
type findings struct{}
|
||||
|
||||
func (findings) Put(key string, value []byte) error {
|
||||
_, err := stdio.State(FindingsState).Put(key, json.RawMessage(value))
|
||||
return err
|
||||
}
|
||||
func (findings) Delete(key string) error { return stdio.State(FindingsState).Delete(key) }
|
||||
|
||||
func main() {
|
||||
c := NewChecker()
|
||||
go func() {
|
||||
|
||||
@@ -33,7 +33,7 @@ const (
|
||||
// Invokes are the tools and seat verbs the probes ask, and Reads the states they read: the manifest's `invokes` and
|
||||
// `reads`, which its test holds to these.
|
||||
var (
|
||||
Invokes = []string{StreamsTool, ClosedTool, SignalsVerb, BannedVerb, PlacementTool, SeatHoldersTool, ModulesTool, ManifestsTool}
|
||||
Invokes = []string{StreamsTool, ClosedTool, SignalsVerb, BannedVerb, PlacementTool, SeatHoldersTool, ModulesTool, ManifestsTool, HandActVerb}
|
||||
Reads = []string{PresenceRead, HealthRead, ReadingsRead, GoodRead}
|
||||
// Consumes are the views families the probes follow (ADR 0615): the indexer's and the assigner's states are asked
|
||||
// once, by their owners' read tools, and then followed by their events, never read.
|
||||
@@ -41,6 +41,9 @@ var (
|
||||
"mesh-delivery-indexer.views.modules", "mesh-delivery-indexer.views.manifests"}
|
||||
)
|
||||
|
||||
// HandActVerb records a re-read of a first view by hand (ADR 0615 §6).
|
||||
const HandActVerb = "seat:mesh-hand-acts.hand-act"
|
||||
|
||||
// The owners' read tools of the states the probes follow, which the manifest invokes.
|
||||
const (
|
||||
PlacementTool = "mesh-delivery-assigner.assigner_read_placement"
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"mesh-delivery-assigner.assigner_read_placement",
|
||||
"mesh-delivery-assigner.assigner_read_seat_holders",
|
||||
"mesh-delivery-indexer.indexer_read_modules",
|
||||
"mesh-delivery-indexer.indexer_read_manifests"
|
||||
"mesh-delivery-indexer.indexer_read_manifests",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"reads": [
|
||||
"mesh-delivery-watchman.presence",
|
||||
|
||||
@@ -17,9 +17,10 @@ import (
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, format+"\n", a...) }
|
||||
@@ -73,7 +74,7 @@ func main() {
|
||||
node := os.Getenv("MESH_NODE")
|
||||
w := NewWatcher(tg, time.Now, logf, node)
|
||||
l := &listening{now: "not yet: starting"}
|
||||
placement := &views.Reader{Module: "mesh-watcher", Logf: logf}
|
||||
placement := &views.Reader{Module: "mesh-watcher", Logf: logf, Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}}
|
||||
placement.Follow(delivery.AssignerModule, delivery.SeatHoldersState, SeatHoldersTool)
|
||||
go run(w, l, node, placement)
|
||||
if err := stdio.Serve("", append(tools(w, l), placement.Tools("watcher")...)); err != nil {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
// The manifest says what the code does: it consumes the heartbeat and nothing else, calls its own
|
||||
@@ -41,7 +41,7 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
|
||||
if !reflect.DeepEqual(m.Consumes, []string{"mesh-self-check.checked", "mesh-delivery-assigner.views.seat-holders"}) {
|
||||
t.Fatalf("consumes %v", m.Consumes)
|
||||
}
|
||||
if !reflect.DeepEqual(m.Invokes, []string{SeatHoldersTool, m.Module + ".watcher_ping"}) || len(m.Reads) != 0 {
|
||||
if !reflect.DeepEqual(m.Invokes, []string{SeatHoldersTool, m.Module + ".watcher_ping", "seat:mesh-hand-acts.hand-act"}) || len(m.Reads) != 0 {
|
||||
t.Fatalf("invokes %v, reads %v", m.Invokes, m.Reads)
|
||||
}
|
||||
if len(m.Claims) != 0 {
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
],
|
||||
"invokes": [
|
||||
"mesh-delivery-assigner.assigner_read_seat_holders",
|
||||
"mesh-watcher.watcher_ping"
|
||||
"mesh-watcher.watcher_ping",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"state": [
|
||||
"findings"
|
||||
],
|
||||
"own-secrets": {
|
||||
"telegram-token": "${dir:state}/telegram-token"
|
||||
|
||||
@@ -17,7 +17,8 @@ import (
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
// Words the manifest gives this bundle (modules/minio/module.json).
|
||||
@@ -28,7 +29,7 @@ const (
|
||||
)
|
||||
|
||||
func main() {
|
||||
seats := &views.Reader{Module: "minio", Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "[object-store] "+f+"\n", a...) }}
|
||||
seats := &views.Reader{Module: "minio", Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "[object-store] "+f+"\n", a...) }}
|
||||
seats.Follow(delivery.AssignerModule, delivery.SeatHoldersState, SeatHoldersTool)
|
||||
s, err := newServer(os.Getenv(ConfigWord), os.Getenv(LinksWord), os.Getenv(ReceivesWord),
|
||||
func() (map[string][]byte, error) { return seats.Values(delivery.SeatHoldersRead) })
|
||||
|
||||
@@ -40,7 +40,7 @@ func TestManifestClaimsTheSeat(t *testing.T) {
|
||||
}
|
||||
invokes, _ := m["invokes"].([]any)
|
||||
consumes, _ := m["consumes"].([]any)
|
||||
if _, reads := m["reads"]; reads || len(invokes) != 1 || invokes[0] != SeatHoldersTool || len(consumes) != 1 || consumes[0] != "mesh-delivery-assigner.views.seat-holders" {
|
||||
if _, reads := m["reads"]; reads || len(invokes) != 2 || invokes[0] != SeatHoldersTool || invokes[1] != "seat:mesh-hand-acts.hand-act" || len(consumes) != 1 || consumes[0] != "mesh-delivery-assigner.views.seat-holders" {
|
||||
t.Fatalf("reads %v, invokes %v, consumes %v: it asks the assigner's seat-holders once and follows its events (ADR 0615)", m["reads"], invokes, consumes)
|
||||
}
|
||||
var goBundle map[string]any
|
||||
|
||||
@@ -40,11 +40,15 @@
|
||||
}
|
||||
],
|
||||
"invokes": [
|
||||
"mesh-delivery-assigner.assigner_read_seat_holders"
|
||||
"mesh-delivery-assigner.assigner_read_seat_holders",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-delivery-assigner.views.seat-holders"
|
||||
],
|
||||
"state": [
|
||||
"findings"
|
||||
],
|
||||
"contributes": {
|
||||
"route": {
|
||||
"api": {
|
||||
|
||||
@@ -22,9 +22,10 @@ import (
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/sdk/views"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
|
||||
// ExportsState is the state the exports are kept in on the bus; MountsState the `mounts` modules' state,
|
||||
@@ -126,7 +127,7 @@ const SeatHoldersTool = delivery.AssignerModule + ".assigner_read_seat_holders"
|
||||
|
||||
// seats is the picture of the placement seat's state of who holds which seat: asked of the assigner once and followed by
|
||||
// its events, never read from its state (ADR 0615).
|
||||
var seats = &views.Reader{Module: "nfs-server", Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "nfs-server: "+f+"\n", a...) }}
|
||||
var seats = &views.Reader{Module: "nfs-server", Findings: views.OwnFindings{}, Acts: handacts.Recorder{Ask: stdio.Ask}, Logf: func(f string, a ...any) { fmt.Fprintf(os.Stderr, "nfs-server: "+f+"\n", a...) }}
|
||||
|
||||
// seatHolderKeys is the placement seat's state of who holds which seat, every key.
|
||||
func seatHolderKeys() (map[string][]byte, error) { return seats.Values(delivery.SeatHoldersRead) }
|
||||
|
||||
@@ -144,7 +144,7 @@ func TestTheManifestCarriesGrantsTheRosterTheWantsAndTheRemovalOrder(t *testing.
|
||||
if len(full.Reads) != 2 || full.Reads[0] != health.ReadingsRead || full.Reads[1] != MountsState {
|
||||
t.Errorf("reads: %v", full.Reads)
|
||||
}
|
||||
if len(full.Invokes) != 1 || full.Invokes[0] != SeatHoldersTool || len(full.Consumes) != 1 || full.Consumes[0] != "mesh-delivery-assigner.views.seat-holders" {
|
||||
if len(full.Invokes) != 2 || full.Invokes[0] != SeatHoldersTool || full.Invokes[1] != "seat:mesh-hand-acts.hand-act" || len(full.Consumes) != 1 || full.Consumes[0] != "mesh-delivery-assigner.views.seat-holders" {
|
||||
t.Errorf("invokes %v, consumes %v", full.Invokes, full.Consumes)
|
||||
}
|
||||
roster := full.Facts["machines"]
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
"name": "exports",
|
||||
"ttl-seconds": 120,
|
||||
"per-machine": true
|
||||
}
|
||||
},
|
||||
"findings"
|
||||
],
|
||||
"reads": [
|
||||
"disk-load.readings",
|
||||
@@ -189,7 +190,8 @@
|
||||
]
|
||||
},
|
||||
"invokes": [
|
||||
"mesh-delivery-assigner.assigner_read_seat_holders"
|
||||
"mesh-delivery-assigner.assigner_read_seat_holders",
|
||||
"seat:mesh-hand-acts.hand-act"
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-delivery-assigner.views.seat-holders"
|
||||
|
||||
Reference in New Issue
Block a user