diff --git a/modules/mesh-build-go/cmd/mesh-build-go/asks.go b/modules/mesh-build-go/cmd/mesh-build-go/asks.go index b138c3973..1ba9be038 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/asks.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/asks.go @@ -84,7 +84,11 @@ func (m *Module) Puller(steps []StepTool, source steprun.AskSource) *steprun.Pul return raw, err } } - return &steprun.Puller{Source: source, Language: sdkstep.AskGo, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys, + var say func(string, any, string) error + if m.SayEvent != nil { + say = steprun.SayOn(sdkstep.AskGo, m.Node, m.SayEvent) + } + return &steprun.Puller{Source: source, Language: sdkstep.AskGo, Say: say, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys, Capacity: capacity, SettingsFile: settings, WatchConfig: watch, CoresPerStep: cores, BuildHours: hours, Logf: m.Say, Has: m.Has, Run: func(ctx context.Context, a sdkstep.StepAsk) (any, error) { if err := m.Check(ctx); err != nil { diff --git a/modules/mesh-build-go/cmd/mesh-build-go/asks_say_test.go b/modules/mesh-build-go/cmd/mesh-build-go/asks_say_test.go new file mode 100644 index 000000000..2c8f1ccdd --- /dev/null +++ b/modules/mesh-build-go/cmd/mesh-build-go/asks_say_test.go @@ -0,0 +1,30 @@ +package main + +import ( + "testing" + + sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" +) + +// Design 47 G §496, §602 (BG4, BN4, BI4): the module's puller says the seat's events on this node's subjects. +func TestPullerSaysTheSeatsEventsOnItsNodesSubject(t *testing.T) { + var subjects []string + m := &Module{Node: "ace", Capacity: func() int { return 0 }, + SayEvent: func(subject string, _ any, _ string) error { subjects = append(subjects, subject); return nil }} + p := m.Puller(nil, steprun.NewFakeAsks()) + if p.Say == nil { + t.Fatal("the puller says no event") + } + seat, _ := sdkstep.BuildSeat(sdkstep.AskGo) + for _, event := range []string{"ask-taken", "step-progress", "step-ended"} { + if err := p.Say(event, nil, "id"); err != nil { + t.Fatal(err) + } + } + for i, event := range []string{"ask-taken", "step-progress", "step-ended"} { + if want := "mesh.seat." + seat + ".event." + event + ".ace"; subjects[i] != want { + t.Errorf("%s said on %s, want %s", event, subjects[i], want) + } + } +} diff --git a/modules/mesh-build-go/cmd/mesh-build-go/builds.go b/modules/mesh-build-go/cmd/mesh-build-go/builds.go index 1bb79f3b0..200b01c75 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/builds.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/builds.go @@ -17,8 +17,8 @@ import ( "path/filepath" "strings" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" ) // layBuilds lays each of builds as the package it names in every module directory dirs (relative to tree) of the diff --git a/modules/mesh-build-go/cmd/mesh-build-go/main.go b/modules/mesh-build-go/cmd/mesh-build-go/main.go index e548a5301..809b1317e 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/main.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/main.go @@ -37,6 +37,7 @@ func main() { } ctx := context.Background() m := &Module{ + SayEvent: stdio.SeatPublish, Node: strings.TrimSpace(os.Getenv("MESH_NODE")), Recipe: Current(), Toolchains: stdio.State(seat.StateToolchains).Put, diff --git a/modules/mesh-build-go/cmd/mesh-build-go/module.go b/modules/mesh-build-go/cmd/mesh-build-go/module.go index c47e8cb70..eee129e90 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/module.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/module.go @@ -24,6 +24,10 @@ const CheckRound = 10 * time.Minute // Module is the Go build module's one running state: the node it runs on, its recipe, the toolchain guard and the // states it writes (toolchains, steps). type Module struct { + // SayEvent publishes an event of the go build seat on a seat subject (stdio.SeatPublish; nil says none, a test's): the + // puller's ask-taken, step-progress and step-ended (design 47 G §496, §602). + SayEvent func(subject string, body any, id string) error + Node string Recipe Recipe // Probe reads the installed Go version (ProbeGo). diff --git a/modules/mesh-build-image/cmd/mesh-build-image/asks.go b/modules/mesh-build-image/cmd/mesh-build-image/asks.go index b2ec10ea7..e2f2e188e 100644 --- a/modules/mesh-build-image/cmd/mesh-build-image/asks.go +++ b/modules/mesh-build-image/cmd/mesh-build-image/asks.go @@ -62,7 +62,11 @@ func (m *Module) Puller(steps []StepTool, source steprun.AskSource) *steprun.Pul if m.ReadPauses.Get != nil { load = func(key string) ([]byte, error) { return m.ReadPauses.Get(key) } } - return &steprun.Puller{Source: source, Language: sdkstep.AskImage, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys, + var say func(string, any, string) error + if m.SayEvent != nil { + say = steprun.SayOn(sdkstep.AskImage, m.Node, m.SayEvent) + } + return &steprun.Puller{Source: source, Language: sdkstep.AskImage, Say: say, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys, Capacity: capacity, SettingsFile: settings, WatchConfig: watch, CoresPerStep: cores, BuildHours: hours, Eligible: m.Eligible, Logf: m.Say, Run: func(ctx context.Context, a sdkstep.StepAsk) (any, error) { if err := m.Check(ctx); err != nil { diff --git a/modules/mesh-build-image/cmd/mesh-build-image/asks_say_test.go b/modules/mesh-build-image/cmd/mesh-build-image/asks_say_test.go new file mode 100644 index 000000000..afe9e94e5 --- /dev/null +++ b/modules/mesh-build-image/cmd/mesh-build-image/asks_say_test.go @@ -0,0 +1,30 @@ +package main + +import ( + "testing" + + sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" +) + +// Design 47 G §496, §602 (BG4, BN4, BI4): the module's puller says the seat's events on this node's subjects. +func TestPullerSaysTheSeatsEventsOnItsNodesSubject(t *testing.T) { + var subjects []string + m := &Module{Node: "ace", Capacity: func() int { return 0 }, + SayEvent: func(subject string, _ any, _ string) error { subjects = append(subjects, subject); return nil }} + p := m.Puller(nil, steprun.NewFakeAsks()) + if p.Say == nil { + t.Fatal("the puller says no event") + } + seat, _ := sdkstep.BuildSeat(sdkstep.AskImage) + for _, event := range []string{"ask-taken", "step-progress", "step-ended"} { + if err := p.Say(event, nil, "id"); err != nil { + t.Fatal(err) + } + } + for i, event := range []string{"ask-taken", "step-progress", "step-ended"} { + if want := "mesh.seat." + seat + ".event." + event + ".ace"; subjects[i] != want { + t.Errorf("%s said on %s, want %s", event, subjects[i], want) + } + } +} diff --git a/modules/mesh-build-image/cmd/mesh-build-image/main.go b/modules/mesh-build-image/cmd/mesh-build-image/main.go index 1d6f7316e..a52d17d40 100644 --- a/modules/mesh-build-image/cmd/mesh-build-image/main.go +++ b/modules/mesh-build-image/cmd/mesh-build-image/main.go @@ -32,6 +32,7 @@ func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, "[mesh-build-image] func main() { ctx := context.Background() m := &Module{ + SayEvent: stdio.SeatPublish, Node: strings.TrimSpace(os.Getenv("MESH_NODE")), RecordAct: handActRecorder, Steps: stdio.State(seat.StateSteps).Put, diff --git a/modules/mesh-build-image/cmd/mesh-build-image/module.go b/modules/mesh-build-image/cmd/mesh-build-image/module.go index c7766ecb1..b9b9bd84b 100644 --- a/modules/mesh-build-image/cmd/mesh-build-image/module.go +++ b/modules/mesh-build-image/cmd/mesh-build-image/module.go @@ -20,6 +20,10 @@ const CheckRound = 10 * time.Minute // Module is the image build module's one running state. type Module struct { + // SayEvent publishes an event of the image build seat on a seat subject (stdio.SeatPublish; nil says none, a test's): the + // puller's ask-taken, step-progress and step-ended (design 47 G §496, §602). + SayEvent func(subject string, body any, id string) error + Node string // RecordAct writes an act in the hand-act log of the seat mesh-hand-acts (§463, §480): a drop writes it first. RecordAct func(what, why string) error diff --git a/modules/mesh-build-image/cmd/mesh-build-image/steps.go b/modules/mesh-build-image/cmd/mesh-build-image/steps.go index df90bee73..4c1566fd1 100644 --- a/modules/mesh-build-image/cmd/mesh-build-image/steps.go +++ b/modules/mesh-build-image/cmd/mesh-build-image/steps.go @@ -7,8 +7,8 @@ package main import ( "fmt" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" seat "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/nodebuildimage" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" stdio "git.novox.be/novox/mesh-sdk/go" ) diff --git a/modules/mesh-build-node/cmd/mesh-build-node/asks.go b/modules/mesh-build-node/cmd/mesh-build-node/asks.go index 5da98ca3b..fcdfdc37e 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/asks.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/asks.go @@ -72,7 +72,11 @@ func (m *Module) Puller(steps []StepTool, source steprun.AskSource) *steprun.Pul if m.ReadPauses.Get != nil { load = func(key string) ([]byte, error) { return m.ReadPauses.Get(key) } } - return &steprun.Puller{Source: source, Language: sdkstep.AskNode, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys, + var say func(string, any, string) error + if m.SayEvent != nil { + say = steprun.SayOn(sdkstep.AskNode, m.Node, m.SayEvent) + } + return &steprun.Puller{Source: source, Language: sdkstep.AskNode, Say: say, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys, Capacity: capacity, SettingsFile: settings, WatchConfig: watch, CoresPerStep: cores, BuildHours: hours, Logf: m.Say, Run: func(ctx context.Context, a sdkstep.StepAsk) (any, error) { if err := m.Prepare(ctx); err != nil { diff --git a/modules/mesh-build-node/cmd/mesh-build-node/asks_say_test.go b/modules/mesh-build-node/cmd/mesh-build-node/asks_say_test.go new file mode 100644 index 000000000..5869cb558 --- /dev/null +++ b/modules/mesh-build-node/cmd/mesh-build-node/asks_say_test.go @@ -0,0 +1,30 @@ +package main + +import ( + "testing" + + sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" +) + +// Design 47 G §496, §602 (BG4, BN4, BI4): the module's puller says the seat's events on this node's subjects. +func TestPullerSaysTheSeatsEventsOnItsNodesSubject(t *testing.T) { + var subjects []string + m := &Module{Node: "ace", Capacity: func() int { return 0 }, + SayEvent: func(subject string, _ any, _ string) error { subjects = append(subjects, subject); return nil }} + p := m.Puller(nil, steprun.NewFakeAsks()) + if p.Say == nil { + t.Fatal("the puller says no event") + } + seat, _ := sdkstep.BuildSeat(sdkstep.AskNode) + for _, event := range []string{"ask-taken", "step-progress", "step-ended"} { + if err := p.Say(event, nil, "id"); err != nil { + t.Fatal(err) + } + } + for i, event := range []string{"ask-taken", "step-progress", "step-ended"} { + if want := "mesh.seat." + seat + ".event." + event + ".ace"; subjects[i] != want { + t.Errorf("%s said on %s, want %s", event, subjects[i], want) + } + } +} diff --git a/modules/mesh-build-node/cmd/mesh-build-node/builds.go b/modules/mesh-build-node/cmd/mesh-build-node/builds.go index b832ee505..7a5c4d640 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/builds.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/builds.go @@ -12,8 +12,8 @@ import ( "os" "path/filepath" - "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep" + "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun" ) // storedBuild is one member's build, read and checked. diff --git a/modules/mesh-build-node/cmd/mesh-build-node/main.go b/modules/mesh-build-node/cmd/mesh-build-node/main.go index adc8aadad..26944e8b0 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/main.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/main.go @@ -40,6 +40,7 @@ func main() { return ReadRegistry(filepath.Join(home, "package-registry.json")) } m := &Module{ + SayEvent: stdio.SeatPublish, Node: strings.TrimSpace(os.Getenv("MESH_NODE")), Reload: func() (Recipe, error) { return ReadRecipe(paths.LockPath()) }, Probe: ProbeNode, diff --git a/modules/mesh-build-node/cmd/mesh-build-node/module.go b/modules/mesh-build-node/cmd/mesh-build-node/module.go index ba5fe8768..d81efb06d 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/module.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/module.go @@ -25,6 +25,10 @@ const CheckRound = 10 * time.Minute // Module is the Node build module's one running state: the node it runs on, its recipe, the toolchain guard, the // toolchain directory and the states it writes (toolchains, steps). type Module struct { + // SayEvent publishes an event of the node build seat on a seat subject (stdio.SeatPublish; nil says none, a test's): the + // puller's ask-taken, step-progress and step-ended (design 47 G §496, §602). + SayEvent func(subject string, body any, id string) error + Node string // Recipe is the recipe in force. Reload, when set, reads it again at every check (the lock file the mesh // writes can change under a running module); a failure to read it is a refusal.