Revert the revert of G's mesh-sdk merge (#191): G's sdk stands again over reader release 3

Main reverted G's half merge (#189, reverted by 8afc3eb in #191) and then took the reader release's S1-S5, which
copied G's code. G's form holds where they differ (process_bus.go, seats.go, state.go and their tests); the
release's kept names stay so main's callers keep building: SeatViewPrefix beside SeatReadPrefix, and QueueInvoke's
empty strings on not-ok (with its test TestQueueInvoke). The tree differs from G's head f30dee54 only by those and
the release's two tests (objects cap option, seat states and stream kinds).

Builds: design 47 G (the milestone's sdk part, as at f30dee54)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-13 12:49:56 +01:00
parent 93e0a7b50d
commit 5fa64be894
211 changed files with 32027 additions and 2484 deletions
+25 -3
View File
@@ -5,6 +5,7 @@ package views_test
import (
"context"
"encoding/json"
"errors"
"fmt"
"testing"
"time"
@@ -21,7 +22,7 @@ import (
// An owner's change is an ordinary event on the shared events stream (novox/hq ADR 0635 §5): a reader that follows the
// owner's state by its read tool hears it on the module's durable consumer of that stream, with no stream of the owner's,
// and a message that is no views event goes to Other.
func TestAReaderHearsAnOwnersChangesAsOrdinaryEvents(t *testing.T) {
func subAReaderHearsAnOwnersChangesAsOrdinaryEvents(t *testing.T) {
nc, err := nats.Connect(testbus.URL(t))
if err != nil {
t.Fatal(err)
@@ -51,7 +52,11 @@ func TestAReaderHearsAnOwnersChangesAsOrdinaryEvents(t *testing.T) {
if _, err := r.Follow("o", "modules", "o.o_read_modules"); err != nil {
t.Fatal(err)
}
r.Start(ctx, js, cred, nil)
statusKV, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: "reader_first-views", Storage: jetstream.MemoryStorage})
if err != nil {
t.Fatal(err)
}
r.Start(ctx, js, cred, process.AwaitBucket(ctx, js, nil, "reader_first-views", "", t.Logf))
<-r.Ready()
pic, err := r.KeyValue(ctx, "o_modules")
if err != nil {
@@ -115,12 +120,22 @@ func TestAReaderHearsAnOwnersChangesAsOrdinaryEvents(t *testing.T) {
if s := f.Status(); s.Asks != 1 {
t.Errorf("the reader asked its first view %d times across the bursts (%s): a revision written over was taken as a gap", s.Asks, s.Why)
}
// G §532, §614: a dropped view's status leaves the state first-views, and so its row of <module>_first_views.
if _, err := statusKV.Get(ctx, views.StatusKey("o", "modules")); err != nil {
t.Fatalf("the status was not kept: %v", err)
}
if err := r.Drop("o", "modules"); err != nil {
t.Fatal(err)
}
if _, err := statusKV.Get(ctx, views.StatusKey("o", "modules")); !errors.Is(err, jetstream.ErrKeyNotFound) {
t.Errorf("the dropped view's status is still kept: %v", err)
}
}
// A module has one durable consumer on the shared events stream, so the loops that hear events in one module must share
// one pull (process.EventHub): two handlers and the views reader on the hub each get their own messages and no other's,
// and a message nobody takes is acknowledged.
func TestTheViewsReaderAndTwoHandlersShareTheModulesOneDurable(t *testing.T) {
func subTheViewsReaderAndTwoHandlersShareTheModulesOneDurable(t *testing.T) {
nc, err := nats.Connect(testbus.URL(t))
if err != nil {
t.Fatal(err)
@@ -222,3 +237,10 @@ func TestTheViewsReaderAndTwoHandlersShareTheModulesOneDurable(t *testing.T) {
t.Fatal("the hub started late heard nothing")
}
}
// TestAReaderHearsAnOwnersChangesAsOrdinaryEvents runs the tests of this package that were merged to keep the module within its test budget (design 47 G §419), each as a subtest.
func TestAReaderHearsAnOwnersChangesAsOrdinaryEvents(t *testing.T) {
t.Run("AReaderHearsAnOwnersChangesAsOrdinaryEvents", subAReaderHearsAnOwnersChangesAsOrdinaryEvents)
t.Run("TheViewsReaderAndTwoHandlersShareTheModulesOneDurable", subTheViewsReaderAndTwoHandlersShareTheModulesOneDurable)
t.Run("WriterSaysItsEventsAndHearsAsksOnTheBus", subWriterSaysItsEventsAndHearsAsksOnTheBus)
}