Fix 9.4d: the tool runner's catalog half uses the follower's Ready and lists the entries by fingerprint in its first views
Builds: design 47 G A-103, §614 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -16,6 +16,10 @@ type FirstViewer interface {
|
||||
Again(ctx context.Context, why string) []error
|
||||
}
|
||||
|
||||
// entryLister is a FirstViewer that also keeps entries by fingerprint (design 47 G A-103): mesh_first_views lists them with their
|
||||
// state and since when.
|
||||
type entryLister interface{ Entries() any }
|
||||
|
||||
// firstViewsAnswer is mesh_first_views and mesh_first_view_again.
|
||||
func (s *Surface) firstViewsAnswer(ctx context.Context, name string, args map[string]any) map[string]any {
|
||||
fv, ok := s.src.(FirstViewer)
|
||||
@@ -24,7 +28,11 @@ func (s *Surface) firstViewsAnswer(ctx context.Context, name string, args map[st
|
||||
"another source")
|
||||
}
|
||||
if name == verbFirstViews {
|
||||
return answerText(map[string]any{"first views": fv.Status()})
|
||||
out := map[string]any{"first views": fv.Status()}
|
||||
if el, ok := fv.(entryLister); ok {
|
||||
out["entries"] = el.Entries()
|
||||
}
|
||||
return answerText(out)
|
||||
}
|
||||
why, _ := args["why"].(string)
|
||||
if why = strings.TrimSpace(why); why == "" {
|
||||
|
||||
@@ -20,6 +20,9 @@ func (v *viewer) Status() []views.Status {
|
||||
return []views.Status{{Owner: "mesh-delivery-assigner", Tool: "assignments", State: "assignments", Revision: 4, Asks: 1}}
|
||||
}
|
||||
|
||||
// Entries are the entries by fingerprint the viewer keeps (design 47 G A-103).
|
||||
func (v *viewer) Entries() any { return []string{"fp:a asked"} }
|
||||
|
||||
func (v *viewer) Again(_ context.Context, why string) []error {
|
||||
v.asked = append(v.asked, why)
|
||||
return nil
|
||||
@@ -35,7 +38,7 @@ func TestTheConsoleShowsAndAsksAgainTheRunnersFirstViews(t *testing.T) {
|
||||
v := &viewer{}
|
||||
var recorded []map[string]any
|
||||
s := &Surface{src: v, who: "desk.node-tools", Record: func(a map[string]any) error { recorded = append(recorded, a); return nil }}
|
||||
if got := text(s.discover(context.Background(), "mesh_first_views", nil)); !strings.Contains(got, "mesh-delivery-assigner") || !strings.Contains(got, "assignments") {
|
||||
if got := text(s.discover(context.Background(), "mesh_first_views", nil)); !strings.Contains(got, "mesh-delivery-assigner") || !strings.Contains(got, "assignments") || !strings.Contains(got, "fp:a asked") {
|
||||
t.Errorf("mesh_first_views shows %s", got)
|
||||
}
|
||||
got := s.discover(context.Background(), "mesh_first_view_again", map[string]any{"why": "doubted"})
|
||||
|
||||
@@ -289,6 +289,14 @@ func (v *Views) Status() []views.Status {
|
||||
return out
|
||||
}
|
||||
|
||||
// Entries are the entries by fingerprint the catalog half's follower keeps, with their state and since when (design 47 G A-103).
|
||||
func (v *Views) Entries() any {
|
||||
if v.branches == nil {
|
||||
return []meshcatalogclient.EntryStatus{}
|
||||
}
|
||||
return v.branches.EntryStatuses()
|
||||
}
|
||||
|
||||
// all is every first view held now: the owners', then the adopted ones.
|
||||
func (v *Views) all() []*views.Follower {
|
||||
v.mu.Lock()
|
||||
@@ -436,30 +444,21 @@ func (v *Views) Modules() (map[string]catalogseat.CatalogEntry, error) {
|
||||
if v.branches == nil {
|
||||
return nil, fmt.Errorf("the tool runner does not follow the catalog half")
|
||||
}
|
||||
followed := v.branches.Followed()
|
||||
if len(followed) == 0 {
|
||||
return nil, fmt.Errorf("the catalog half names no watched branch yet (the registrations of %s are asked until they answer)", catalogseat.Seat)
|
||||
if err := v.branches.Ready(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := map[string]catalogseat.CatalogEntry{}
|
||||
var waiting []string
|
||||
for _, branch := range followed {
|
||||
for _, branch := range v.branches.Followed() {
|
||||
c, ok := v.branches.Catalog(branch)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
half, held := c.View()
|
||||
if !held {
|
||||
waiting = append(waiting, branch)
|
||||
continue
|
||||
}
|
||||
half, _ := c.View() // a branch at none-yet is ready and empty (§614)
|
||||
for m, e := range half.Entries {
|
||||
if _, taken := out[m]; !taken {
|
||||
out[m] = e
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(waiting) > 0 {
|
||||
return nil, fmt.Errorf("the catalog half has no first view of %s yet", strings.Join(waiting, ", "))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user