S4 catalog-ready-on-a-fresh-mesh: with the registrations and the gate's source answered and naming no branch, Ready is nil and the view is empty
Builds: design 47 G A-368 (G-22-lead-answers-2.md), start-waits.md S4 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -12,10 +12,16 @@ import (
|
||||
)
|
||||
|
||||
// Ready is nil once every watched branch has its first view (`none-yet` counting as one), else says what it waits for
|
||||
// (design 47 G §614, A-103): a part acts on nothing until then.
|
||||
// (design 47 G §614, A-103): a part acts on nothing until then. On a fresh mesh, where the registrations and the gate's source are both
|
||||
// answered and name no branch, it is nil too: the trunk is `none-yet` (A-368).
|
||||
func (b *Branches) Ready() error {
|
||||
followed := b.Followed()
|
||||
if len(followed) == 0 {
|
||||
// A fresh mesh: the registrations and the gate's source are both answered and name no branch, so the trunk is `none-yet`
|
||||
// and the view is empty (design 47 G, A-368).
|
||||
if b.namesNoBranch() {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("the catalog half names no watched branch yet (the registrations of the seat %s are asked until they answer)", seat.Seat)
|
||||
}
|
||||
var waiting []string
|
||||
@@ -34,6 +40,28 @@ func (b *Branches) Ready() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// namesNoBranch says the first view of the registrations is in and, while the gate's source is followed, so is its, and
|
||||
// neither names a branch (none is followed).
|
||||
func (b *Branches) namesNoBranch() bool {
|
||||
select {
|
||||
case <-b.Registrations.Ready():
|
||||
default:
|
||||
return false
|
||||
}
|
||||
b.mu.Lock()
|
||||
s := b.source
|
||||
b.mu.Unlock()
|
||||
if s == nil {
|
||||
return true
|
||||
}
|
||||
select {
|
||||
case <-s.Follower.Ready():
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Entry is a module's entry at the trunk: the module's own registration decides, so the branch followed first, which lists
|
||||
// the module, is the one read (design 47 G A-103). An error says a watched branch has no first view yet, never "no module".
|
||||
func (b *Branches) Entry(module string) (seat.CatalogEntry, bool, error) {
|
||||
|
||||
@@ -94,3 +94,44 @@ func TestTheBranchFollowerGivesEveryPartItsEntryHelpers(t *testing.T) {
|
||||
t.Error("a released entry kept its finding")
|
||||
}
|
||||
}
|
||||
|
||||
// A-368 (design 47 G, C6): on a fresh mesh, where neither the registrations nor the gate's source name a branch, the catalog half
|
||||
// counts the trunk as `none-yet`: Ready is nil once both are answered, and the view is empty (Entry finds no module); until
|
||||
// both answer, no part is ready.
|
||||
func TestAMeshThatNamesNoBranchIsReadyWithAnEmptyView(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
for _, c := range []struct {
|
||||
name string
|
||||
start []string // the followers started, by the name they are adopted under
|
||||
ready bool
|
||||
}{
|
||||
{"nothing answered", nil, false},
|
||||
{"only the registrations answered", []string{"mesh-catalog.registrations"}, false},
|
||||
{"only the gate's source answered", []string{"mesh-delivery.source"}, false},
|
||||
{"both answered", []string{"mesh-catalog.registrations", "mesh-delivery.source"}, true},
|
||||
} {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
seats := &fakeSeats{regs: map[string][]string{}}
|
||||
w := &fakeWiring{adopted: map[string]*views.Follower{}, hears: map[string]func(context.Context, []byte) error{}}
|
||||
b, err := NewBranches(w, seats.call)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, name := range c.start {
|
||||
f, _ := w.get(name)
|
||||
if err := f.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := b.Ready(); (err == nil) != c.ready {
|
||||
t.Fatalf("Ready = %v, want ready %v", err, c.ready)
|
||||
}
|
||||
if c.ready {
|
||||
if e, found, err := b.Entry("m"); err != nil || found {
|
||||
t.Errorf("Entry = %v, %v, %v: want an empty view, no error", e, found, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user