net/netmon: do not abandon a subscriber when exiting early (#17899) (#17905)

LinkChangeLogLimiter keeps a subscription to track rate limits for log
messages.  But when its context ended, it would exit the subscription loop,
leaving the subscriber still alive. Ensure the subscriber gets cleaned up
when the context ends, so we don't stall event processing.

Updates tailscale/corp#34311

Change-Id: I82749e482e9a00dfc47f04afbc69dd0237537cb2

(cherry picked from commit ab4b990d51c41aff8e1ae7a08435dedfe621ce0d)

Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Co-authored-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
Jonathan Nobels 2025-11-17 15:40:46 -05:00 committed by GitHub
parent ea8eeeb2f7
commit fa514c7280
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -18,13 +18,13 @@ import (
// done.
func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) logger.Logf {
var formatSeen sync.Map // map[string]bool
nm.b.Monitor(nm.changeDeltaWatcher(nm.b, ctx, func(cd ChangeDelta) {
sub := eventbus.SubscribeFunc(nm.b, 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, sub.Close)
return func(format string, args ...any) {
// We only store 'true' in the map, so if it's present then it
// means we've already logged this format string.
@ -42,19 +42,3 @@ 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)
}
}
}
}