net/netmon: remove usage of direct callbacks from netmon (#17292)

The callback itself is not removed as it is used in other repos, making
it simpler for those to slowly transition to the eventbus.

Updates #15160

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
Claus Lensbøl
2025-10-01 14:59:38 -04:00
committed by GitHub
parent 6f7ce5eb5d
commit ce752b8a88
28 changed files with 217 additions and 48 deletions
+19 -3
View File
@@ -8,6 +8,7 @@ import (
"sync"
"tailscale.com/types/logger"
"tailscale.com/util/eventbus"
)
// LinkChangeLogLimiter returns a new [logger.Logf] that logs each unique
@@ -17,13 +18,12 @@ import (
// done.
func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) logger.Logf {
var formatSeen sync.Map // map[string]bool
unregister := nm.RegisterChangeCallback(func(cd *ChangeDelta) {
nm.b.Monitor(nm.changeDeltaWatcher(nm.b, ctx, func(cd ChangeDelta) {
// If we're in a major change or a time jump, clear the seen map.
if cd.Major || cd.TimeJumped {
formatSeen.Clear()
}
})
context.AfterFunc(ctx, unregister)
}))
return func(format string, args ...any) {
// We only store 'true' in the map, so if it's present then it
@@ -42,3 +42,19 @@ func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) lo
logf(format, args...)
}
}
func (nm *Monitor) changeDeltaWatcher(ec *eventbus.Client, ctx context.Context, fn func(ChangeDelta)) func(*eventbus.Client) {
sub := eventbus.Subscribe[ChangeDelta](ec)
return func(ec *eventbus.Client) {
for {
select {
case <-ctx.Done():
return
case <-sub.Done():
return
case change := <-sub.Events():
fn(change)
}
}
}
}
+8 -13
View File
@@ -11,6 +11,7 @@ import (
"testing/synctest"
"tailscale.com/util/eventbus"
"tailscale.com/util/eventbus/eventbustest"
)
func TestLinkChangeLogLimiter(t *testing.T) { synctest.Test(t, syncTestLinkChangeLogLimiter) }
@@ -61,21 +62,15 @@ func syncTestLinkChangeLogLimiter(t *testing.T) {
// string cache and allow the next log to write to our log buffer.
//
// InjectEvent doesn't work because it's not a major event, so we
// instead reach into the netmon and grab the callback, and then call
// it ourselves.
mon.mu.Lock()
var cb func(*ChangeDelta)
for _, c := range mon.cbs {
cb = c
break
}
mon.mu.Unlock()
cb(&ChangeDelta{Major: true})
// instead inject the event ourselves.
injector := eventbustest.NewInjector(t, bus)
eventbustest.Inject(injector, ChangeDelta{Major: true})
synctest.Wait()
logf("hello %s", "world")
if got := logBuffer.String(); got != "hello world\nother message\nhello world\n" {
t.Errorf("unexpected log buffer contents: %q", got)
want := "hello world\nother message\nhello world\n"
if got := logBuffer.String(); got != want {
t.Errorf("unexpected log buffer contents, got: %q, want, %q", got, want)
}
// Canceling the context we passed to LinkChangeLogLimiter should