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
This commit is contained in:
2026-11-12 11:42:11 +01:00
parent e436c59430
commit c82b40660b
4 changed files with 10 additions and 33 deletions
@@ -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
}
}
@@ -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")
}
})
+1 -10
View File
@@ -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
+4 -4
View File
@@ -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")
}
}