From c82b40660ba5401be698bd74a10c8c3e34a4a340 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 11:42:11 +0100 Subject: [PATCH] A-278 (join 11): mesh-recovery and nats pass mesh-sdk's seatlist.Definition to AnswerSeat Builds: design 47 G A-278 (answers G-22) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- modules/mesh-recovery/cmd/mesh-recovery/main.go | 16 +--------------- .../mesh-recovery/cmd/mesh-recovery/main_test.go | 8 ++++---- modules/nats/cmd/nats-tools/keep.go | 11 +---------- modules/nats/cmd/nats-tools/keep_test.go | 8 ++++---- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/modules/mesh-recovery/cmd/mesh-recovery/main.go b/modules/mesh-recovery/cmd/mesh-recovery/main.go index edeb28a9d..7b08ab52a 100644 --- a/modules/mesh-recovery/cmd/mesh-recovery/main.go +++ b/modules/mesh-recovery/cmd/mesh-recovery/main.go @@ -20,7 +20,6 @@ import ( "git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient" "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions" "git.novox.be/novox/mesh-sdk/go/process" - "git.novox.be/novox/mesh-sdk/go/seatdef" "git.novox.be/novox/mesh-sdk/go/seatlist" "git.novox.be/novox/mesh-sdk/go/views" @@ -186,7 +185,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro logger.Printf("the consumer %s is not bound yet (%v): bound once the bus makes it, the seat list read then", account.EventConsumerName(), err) } defer hub.Stop() - stopAnswers, err := conn.AnswerSeat(recovery.Seat, seatDefinition(seats, recovery.Seat), e.Handlers()) + stopAnswers, err := conn.AnswerSeat(recovery.Seat, seatlist.Definition(seats.Reader, recovery.Seat), e.Handlers()) if err != nil { return fmt.Errorf("the seat %s's verbs cannot be answered: %w", recovery.Seat, err) } @@ -211,16 +210,3 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro stopAnswers() return nil } - -// seatDefinition is the definition of seat the seat list holds (A-186): false until the seat mesh-catalog has answered the -// list, so the module answers a verb only once its seat list is read, and false for a seat it does not hold. -func seatDefinition(seats *seatlist.Part, seat string) func() (seatdef.Definition, bool) { - return func() (seatdef.Definition, bool) { - r := seats.Reader() - if r == nil || !r.Status().Heard { - return seatdef.Definition{}, false - } - d, ok := r.Definitions()[seat] - return d, ok - } -} diff --git a/modules/mesh-recovery/cmd/mesh-recovery/main_test.go b/modules/mesh-recovery/cmd/mesh-recovery/main_test.go index 5205d8c1c..413076145 100644 --- a/modules/mesh-recovery/cmd/mesh-recovery/main_test.go +++ b/modules/mesh-recovery/cmd/mesh-recovery/main_test.go @@ -46,17 +46,17 @@ func TestWhatTheProcessReads(t *testing.T) { } return p } - if _, ok := seatDefinition(seatlist.NewPart("recovery", nil), meshbroker.Seat)(); ok { + if _, ok := seatlist.Definition(seatlist.NewPart("recovery", nil).Reader, meshbroker.Seat)(); ok { t.Error("a definition is answered before the seat list's reader started") } - if _, ok := seatDefinition(follow(true), meshbroker.Seat)(); ok { + if _, ok := seatlist.Definition(follow(true).Reader, meshbroker.Seat)(); ok { t.Error("a definition is answered while the seat mesh-catalog has not answered the list") } read := follow(false) - if d, ok := seatDefinition(read, meshbroker.Seat)(); !ok || d.Seat != meshbroker.Seat { + if d, ok := seatlist.Definition(read.Reader, meshbroker.Seat)(); !ok || d.Seat != meshbroker.Seat { t.Errorf("the read list's %s is answered as %q, %v", meshbroker.Seat, d.Seat, ok) } - if _, ok := seatDefinition(read, "no-such-seat")(); ok { + if _, ok := seatlist.Definition(read.Reader, "no-such-seat")(); ok { t.Error("a seat the list does not hold is answered a definition") } }) diff --git a/modules/nats/cmd/nats-tools/keep.go b/modules/nats/cmd/nats-tools/keep.go index 93afd23b7..366aacda6 100644 --- a/modules/nats/cmd/nats-tools/keep.go +++ b/modules/nats/cmd/nats-tools/keep.go @@ -242,7 +242,7 @@ func runKeeper(ctx context.Context, getenv func(string) string, logOut io.Writer } k.Catalog, k.Seats, k.Again = follow.view, follow.seats, follow.again // The process answers the seat mesh-broker's snapshot verbs itself (design 47 G ยง681, A-107), with the caller the bus proved. - stopAnswers, err := conn.AnswerSeat(meshbroker.Seat, follow.definition(meshbroker.Seat), snapshotAnswers(k, heldRequest(k.Store), keeperSnapshots(nc, logger.Printf))) + stopAnswers, err := conn.AnswerSeat(meshbroker.Seat, seatlist.Definition(func() *seatlist.Reader { return follow.seatList }, meshbroker.Seat), snapshotAnswers(k, heldRequest(k.Store), keeperSnapshots(nc, logger.Printf))) if err != nil { return fmt.Errorf("the seat %s's snapshot verbs cannot be answered: %w", meshbroker.Seat, err) } @@ -318,15 +318,6 @@ func (f *catalogFollow) seats() map[string]seatdef.Definition { return f.seatList.Definitions() } -// definition is the definition of seat the seat list holds, which the seat's verbs answered by the process check their callers -// against (process.Conn.AnswerSeat; design 47 G lead answers A-179, A-186): none until the seat has answered, as seats says. -func (f *catalogFollow) definition(seat string) func() (seatdef.Definition, bool) { - return func() (seatdef.Definition, bool) { - d, ok := f.seats()[seat] - return d, ok - } -} - // again asks every first view of the catalog half and the seat list again, by hand. func (f *catalogFollow) again() error { var errs []error diff --git a/modules/nats/cmd/nats-tools/keep_test.go b/modules/nats/cmd/nats-tools/keep_test.go index d42ca1858..a5724d859 100644 --- a/modules/nats/cmd/nats-tools/keep_test.go +++ b/modules/nats/cmd/nats-tools/keep_test.go @@ -131,17 +131,17 @@ func TestTheAnsweredSeatsDefinitionIsTheSeatListsOnceRead(t *testing.T) { <-r.Ready() return &catalogFollow{seatList: r} } - if _, ok := (&catalogFollow{}).definition(meshbroker.Seat)(); ok { + if _, ok := seatlist.Definition(func() *seatlist.Reader { return (&catalogFollow{}).seatList }, meshbroker.Seat)(); ok { t.Error("a definition is answered with no seat list") } - if _, ok := follow(true).definition(meshbroker.Seat)(); ok { + if _, ok := seatlist.Definition(func() *seatlist.Reader { return follow(true).seatList }, meshbroker.Seat)(); ok { t.Error("a definition is answered while the seat mesh-catalog has not answered the list") } read := follow(false) - if d, ok := read.definition(meshbroker.Seat)(); !ok || d.Seat != meshbroker.Seat { + if d, ok := seatlist.Definition(func() *seatlist.Reader { return read.seatList }, meshbroker.Seat)(); !ok || d.Seat != meshbroker.Seat { t.Errorf("the read list's %s is answered as %q, %v", meshbroker.Seat, d.Seat, ok) } - if _, ok := read.definition("no-such-seat")(); ok { + if _, ok := seatlist.Definition(func() *seatlist.Reader { return read.seatList }, "no-such-seat")(); ok { t.Error("a seat the list does not hold is answered a definition") } }