From 52a0cc4fcb11cc9fc789b3ec047c3bd049925e11 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 5 Oct 2026 15:38:30 +0200 Subject: [PATCH] Forget a runtime's old instance once it answers under a new one, so a restart is not reported as a missed answer --- node-tools/internal/console/runtimes.go | 11 +++++++++++ node-tools/internal/console/runtimes_test.go | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/node-tools/internal/console/runtimes.go b/node-tools/internal/console/runtimes.go index aa1fa7b..855b28f 100644 --- a/node-tools/internal/console/runtimes.go +++ b/node-tools/internal/console/runtimes.go @@ -81,6 +81,17 @@ func (s *Surface) remember(x *index) { heard[k] = true s.runtimes[k] = seen } + // A runtime restarted answers under a new instance id: the old one is gone, not silent, and saying + // it was missed would hide nothing but cry wolf after every restart. + now := map[string]bool{} + for k := range heard { + now[s.runtimes[k].Name+"@"+s.runtimes[k].Machine] = true + } + for k, r := range s.runtimes { + if !heard[k] && r.Machine != "" && now[r.Name+"@"+r.Machine] { + delete(s.runtimes, k) + } + } silent := map[string]string{} for _, u := range x.Discovery.Silent { silent[runtimeKey(u.Name, u.ID)] = fmt.Sprintf("it answered PING; what it serves did not arrive within %s", announce.Patience) diff --git a/node-tools/internal/console/runtimes_test.go b/node-tools/internal/console/runtimes_test.go index 5911e87..c82d48a 100644 --- a/node-tools/internal/console/runtimes_test.go +++ b/node-tools/internal/console/runtimes_test.go @@ -198,3 +198,22 @@ func TestARuntimeHeardBeforeAndNotNowIsNamed(t *testing.T) { t.Errorf("%v", err) } } + +// A runtime restarted answers under a new instance id; its old instance is gone, not unheard. +func TestARestartedRuntimeIsNotNamedUnheard(t *testing.T) { + heard := func(id string) *index { + return &index{Modules: map[string]*moduleInfo{}, Recorded: map[string][]string{}, Discovery: announce.Discovery{At: time.Now().UTC(), + Heard: []announce.Heard{{Info: micro.Info{ServiceIdentity: micro.ServiceIdentity{Name: "node-tools", ID: id, + Metadata: map[string]string{"node": "laptop"}}}}}}} + } + s := &Surface{} + s.remember(heard("before-restart")) + after := heard("after-restart") + s.remember(after) + if len(after.Unheard) != 0 { + t.Errorf("a restarted runtime was named unheard: %+v", after.Unheard) + } + if len(s.runtimes) != 1 { + t.Errorf("the old instance is still kept: %d runtimes", len(s.runtimes)) + } +}