health: avoid publishing health.Change when warnable visibility remains unchanged
Warnables with a non-zero TimeToVisible are only published on the eventbus when they remain unhealthy long enough to become visible. However, we still publish a health.Change when a warning that was never visible (and was never published to the eventbus) becomes healthy. This PR fixes that and reduces churn when there is no actual state change. In particular, it avoids unnecessary IPN bus notifications sent to GUI/CLI clients, captive portal detection, etc. Updates tailscale/corp#39759 (noticed while working on it) Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
+23
-5
@@ -492,7 +492,12 @@ func (t *Tracker) SetHealthy(w *Warnable) {
|
||||
}
|
||||
|
||||
func (t *Tracker) setHealthyLocked(w *Warnable) {
|
||||
if !buildfeatures.HasHealth || t.warnableVal[w] == nil {
|
||||
if !buildfeatures.HasHealth {
|
||||
return
|
||||
}
|
||||
|
||||
ws := t.warnableVal[w]
|
||||
if ws == nil {
|
||||
// Nothing to remove
|
||||
return
|
||||
}
|
||||
@@ -501,15 +506,28 @@ func (t *Tracker) setHealthyLocked(w *Warnable) {
|
||||
|
||||
// Stop any pending visiblity timers for this Warnable
|
||||
if canc, ok := t.pendingVisibleTimers[w]; ok {
|
||||
// We removed the warningState for this Warnable,
|
||||
// and we hold the lock, so even if the timer callback
|
||||
// has already started, it won't find a warningState
|
||||
// for this Warnable and won't publish any changes.
|
||||
canc.Stop()
|
||||
delete(t.pendingVisibleTimers, w)
|
||||
}
|
||||
|
||||
change := Change{
|
||||
WarnableChanged: true,
|
||||
Warnable: w,
|
||||
// Only publish a change if the Warnable was unhealthy long
|
||||
// enough to become visible to the user. Otherwise, it would
|
||||
// not have been published as unhealthy, so there is no need
|
||||
// to publish it as healthy. This prevents eventbus (and by
|
||||
// extension the IPN bus) churn for Warnables that are marked
|
||||
// unhealthy and then healthy again. Notably, this includes
|
||||
// warnables touched by [Tracker.updateBuiltinWarnablesLocked].
|
||||
if w.IsVisible(ws, t.now) {
|
||||
change := Change{
|
||||
WarnableChanged: true,
|
||||
Warnable: w,
|
||||
}
|
||||
t.changePub.Publish(change)
|
||||
}
|
||||
t.changePub.Publish(change)
|
||||
}
|
||||
|
||||
// notifyWatchersControlChangedLocked calls each watcher to signal that control
|
||||
|
||||
Reference in New Issue
Block a user