tka: keep the CompactionDefaults alongside the other limits #6
+23
-5
@@ -492,7 +492,12 @@ func (t *Tracker) SetHealthy(w *Warnable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracker) setHealthyLocked(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
|
// Nothing to remove
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -501,15 +506,28 @@ func (t *Tracker) setHealthyLocked(w *Warnable) {
|
|||||||
|
|
||||||
// Stop any pending visiblity timers for this Warnable
|
// Stop any pending visiblity timers for this Warnable
|
||||||
if canc, ok := t.pendingVisibleTimers[w]; ok {
|
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()
|
canc.Stop()
|
||||||
delete(t.pendingVisibleTimers, w)
|
delete(t.pendingVisibleTimers, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
change := Change{
|
// Only publish a change if the Warnable was unhealthy long
|
||||||
WarnableChanged: true,
|
// enough to become visible to the user. Otherwise, it would
|
||||||
Warnable: w,
|
// 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
|
// notifyWatchersControlChangedLocked calls each watcher to signal that control
|
||||||
|
|||||||
+86
-43
@@ -271,47 +271,91 @@ func TestSetUnhealthyWithTimeToVisible(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(*testing.T) {
|
t.Run(tt.name, func(*testing.T) {
|
||||||
bus := eventbustest.NewBus(t)
|
synctest.Test(t, func(t *testing.T) {
|
||||||
ht := NewTracker(bus)
|
clock := tstest.NewClock(tstest.ClockOpts{
|
||||||
mw := Register(&Warnable{
|
Start: time.Unix(123, 0),
|
||||||
Code: "test-warnable-3-secs-to-visible",
|
FollowRealTime: false,
|
||||||
Title: "Test Warnable with 3 seconds to visible",
|
})
|
||||||
Text: StaticMessage("Hello world"),
|
bus := eventbustest.NewBus(t)
|
||||||
TimeToVisible: 2 * time.Second,
|
ht := NewTracker(bus)
|
||||||
ImpactsConnectivity: true,
|
ht.testClock = clock
|
||||||
|
mw := Register(&Warnable{
|
||||||
|
Code: "test-warnable-3-secs-to-visible",
|
||||||
|
Title: "Test Warnable with 3 seconds to visible",
|
||||||
|
Text: StaticMessage("Hello world"),
|
||||||
|
TimeToVisible: 2 * time.Second,
|
||||||
|
ImpactsConnectivity: true,
|
||||||
|
})
|
||||||
|
defer unregister(mw)
|
||||||
|
|
||||||
|
becameUnhealthy := make(chan struct{})
|
||||||
|
becameHealthy := make(chan struct{})
|
||||||
|
|
||||||
|
watchFunc := func(c Change) {
|
||||||
|
w := c.Warnable
|
||||||
|
us := c.UnhealthyState
|
||||||
|
if w != mw {
|
||||||
|
t.Fatalf("watcherFunc was called, but with an unexpected Warnable: %v, want: %v", w, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
if us != nil {
|
||||||
|
becameUnhealthy <- struct{}{}
|
||||||
|
} else {
|
||||||
|
becameHealthy <- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tt.preFunc(t, ht, bus, watchFunc)
|
||||||
|
ht.SetUnhealthy(mw, Args{ArgError: "Hello world"})
|
||||||
|
|
||||||
|
// Advance time by half of the TimeToVisible duration.
|
||||||
|
clock.Advance(mw.TimeToVisible / 2)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-becameUnhealthy:
|
||||||
|
// Test failed because the watcher got notified of an unhealthy state
|
||||||
|
t.Fatalf("watcherFunc was called with an unhealthy state")
|
||||||
|
case <-becameHealthy:
|
||||||
|
// Test failed because the watcher got of a healthy state
|
||||||
|
t.Fatalf("watcherFunc was called with a healthy state")
|
||||||
|
default:
|
||||||
|
// As expected, watcherFunc still had not been called
|
||||||
|
// after mw.TimeToVisible / 2.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance time to get past the the TimeToVisible duration.
|
||||||
|
// The watcher should be notified of the unhealthy state.
|
||||||
|
clock.Advance(mw.TimeToVisible/2 + 1)
|
||||||
|
<-becameUnhealthy
|
||||||
|
|
||||||
|
// Reset the warnable to neutral / healthy state before
|
||||||
|
// the next part of the test.
|
||||||
|
ht.SetHealthy(mw)
|
||||||
|
<-becameHealthy
|
||||||
|
|
||||||
|
// Mark the warnable unhealthy and then immediately healthy
|
||||||
|
// before the TimeToVisible duration elapses.
|
||||||
|
// The watcher should not be notified of either change
|
||||||
|
// because the warnable never became visible.
|
||||||
|
ht.SetUnhealthy(mw, Args{ArgError: "Hello world"})
|
||||||
|
ht.SetHealthy(mw)
|
||||||
|
|
||||||
|
// Advance to get past the the TimeToVisible delay.
|
||||||
|
clock.Advance(mw.TimeToVisible * 2)
|
||||||
|
synctest.Wait()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-becameUnhealthy:
|
||||||
|
// Test failed because the watcher got notified of an unhealthy state
|
||||||
|
t.Fatalf("watcherFunc was called with an unhealthy state")
|
||||||
|
case <-becameHealthy:
|
||||||
|
// Test failed because the watcher got of a healthy state
|
||||||
|
t.Fatalf("watcherFunc was called with a healthy state")
|
||||||
|
default:
|
||||||
|
// As expected, watcherFunc was not called after marking
|
||||||
|
// the warnable healthy again as it never became visible.
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
becameUnhealthy := make(chan struct{})
|
|
||||||
becameHealthy := make(chan struct{})
|
|
||||||
|
|
||||||
watchFunc := func(c Change) {
|
|
||||||
w := c.Warnable
|
|
||||||
us := c.UnhealthyState
|
|
||||||
if w != mw {
|
|
||||||
t.Fatalf("watcherFunc was called, but with an unexpected Warnable: %v, want: %v", w, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
if us != nil {
|
|
||||||
becameUnhealthy <- struct{}{}
|
|
||||||
} else {
|
|
||||||
becameHealthy <- struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tt.preFunc(t, ht, bus, watchFunc)
|
|
||||||
ht.SetUnhealthy(mw, Args{ArgError: "Hello world"})
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-becameUnhealthy:
|
|
||||||
// Test failed because the watcher got notified of an unhealthy state
|
|
||||||
t.Fatalf("watcherFunc was called with an unhealthy state")
|
|
||||||
case <-becameHealthy:
|
|
||||||
// Test failed because the watcher got of a healthy state
|
|
||||||
t.Fatalf("watcherFunc was called with a healthy state")
|
|
||||||
case <-time.After(1 * time.Second):
|
|
||||||
// As expected, watcherFunc still had not been called after 1 second
|
|
||||||
}
|
|
||||||
unregister(mw)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -739,12 +783,11 @@ func TestControlHealthNotifies(t *testing.T) {
|
|||||||
ht.SetIPNState("NeedsLogin", true)
|
ht.SetIPNState("NeedsLogin", true)
|
||||||
ht.GotStreamedMapResponse()
|
ht.GotStreamedMapResponse()
|
||||||
|
|
||||||
// Expect events at starup, before doing anything else, skip unstable
|
// Expect events at starup, before doing anything else, skip
|
||||||
// event and no warning event as they show up at different times.
|
// the warming up events.
|
||||||
synctest.Wait()
|
synctest.Wait()
|
||||||
if err := eventbustest.Expect(tw,
|
if err := eventbustest.Expect(tw,
|
||||||
CompareWarnableCode(t, tsconst.HealthWarnableWarmingUp),
|
CompareWarnableCode(t, tsconst.HealthWarnableWarmingUp),
|
||||||
CompareWarnableCode(t, tsconst.HealthWarnableNotInMapPoll),
|
|
||||||
CompareWarnableCode(t, tsconst.HealthWarnableWarmingUp),
|
CompareWarnableCode(t, tsconst.HealthWarnableWarmingUp),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
t.Errorf("startup error: %v", err)
|
t.Errorf("startup error: %v", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user