mirror of
https://github.com/tailscale/tailscale.git
synced 2025-09-21 13:41:46 +02:00
Remove the need for the caller to hold on to and call an unregister function. Both two callers (one real, one test) already have a context they can use. Use context.AfterFunc instead. There are no observable side effects from scheduling too late if the goroutine doesn't run sync. Updates #17148 Change-Id: Ie697dae0e797494fa8ef27fbafa193bfe5ceb307 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
45 lines
1.3 KiB
Go
45 lines
1.3 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package netmon
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"tailscale.com/types/logger"
|
|
)
|
|
|
|
// LinkChangeLogLimiter returns a new [logger.Logf] that logs each unique
|
|
// format string to the underlying logger only once per major LinkChange event.
|
|
//
|
|
// The logger stops tracking seen format strings when the provided context is
|
|
// 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) {
|
|
// 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
|
|
// means we've already logged this format string.
|
|
_, loaded := formatSeen.LoadOrStore(format, true)
|
|
if loaded {
|
|
// TODO(andrew-d): we may still want to log this
|
|
// message every N minutes (1x/hour?) even if it's been
|
|
// seen, so that debugging doesn't require searching
|
|
// back in the logs for an unbounded amount of time.
|
|
//
|
|
// See: https://github.com/tailscale/tailscale/issues/13145
|
|
return
|
|
}
|
|
|
|
logf(format, args...)
|
|
}
|
|
}
|