plugin: watchdog must assume a reset write may have just happened after restart using defer (#31635)
This commit is contained in:
parent
c52b4a79ea
commit
623427e728
2 changed files with 16 additions and 7 deletions
|
|
@ -79,7 +79,9 @@ type deferredState[T comparable] struct {
|
|||
// it is currently not possible to write this as a method
|
||||
func setter[T comparable](o *watchdogPlugin, set func(T) error, reset []T) func(T) error {
|
||||
var state *deferredState[T]
|
||||
var lastUpdated time.Time
|
||||
// seed with now, not zero: otherwise the first write's delay computes to 0 and skips
|
||||
// deferral, which is wrong for an unknown last write
|
||||
lastUpdated := o.clock.Now()
|
||||
var last *T
|
||||
|
||||
// stop running wdt
|
||||
|
|
@ -144,7 +146,7 @@ func setter[T comparable](o *watchdogPlugin, set func(T) error, reset []T) func(
|
|||
delay := max(0, o.timeout+5*time.Second-o.clock.Since(lastUpdated))
|
||||
|
||||
// defer update to non-reset value
|
||||
if o.deferred && delay > 0 && !lastUpdated.IsZero() && !slices.Contains(reset, val) {
|
||||
if o.deferred && delay > 0 && !slices.Contains(reset, val) {
|
||||
stopWdt()
|
||||
|
||||
// store deferred value
|
||||
|
|
|
|||
|
|
@ -113,26 +113,33 @@ func TestWatchdogCancelPendingDeferredUpdate(t *testing.T) {
|
|||
return nil
|
||||
}, []int{1}) // 1 is reset value
|
||||
|
||||
// Value 3 (non-reset)
|
||||
// Value 1 (reset) → establishes a known write time so the subsequent non-reset
|
||||
// writes below are deferred based on that, not the fresh-setter startup assumption
|
||||
require.NoError(t, set(1))
|
||||
require.Equal(t, []int{1}, calls)
|
||||
|
||||
// Value 3 (non-reset) → deferred (no time has passed since the reset write)
|
||||
require.NoError(t, set(3))
|
||||
require.Equal(t, []int{3}, calls)
|
||||
require.Equal(t, []int{1}, calls, "Value 3 should not be set yet")
|
||||
c.Add(timeout + 5*time.Second)
|
||||
require.Equal(t, []int{1, 3}, calls)
|
||||
|
||||
// Value 2 (deferred update)
|
||||
require.NoError(t, set(2))
|
||||
require.Equal(t, []int{3}, calls, "Value 2 should not be set yet")
|
||||
require.Equal(t, []int{1, 3}, calls, "Value 2 should not be set yet")
|
||||
|
||||
// Wait a bit but not the full delay
|
||||
c.Add(30 * time.Second)
|
||||
|
||||
// Value 1 (reset) → should cancel pending deferred update and set immediately
|
||||
require.NoError(t, set(1))
|
||||
require.Equal(t, []int{3, 1}, calls, "Value 1 should be set, Value 2 should be cancelled")
|
||||
require.Equal(t, []int{1, 3, 1}, calls, "Value 1 should be set, Value 2 should be cancelled")
|
||||
|
||||
// Wait for what would have been the original delay
|
||||
c.Add(timeout + 5*time.Second)
|
||||
|
||||
// Value 2 should still not have been set
|
||||
require.Equal(t, []int{3, 1}, calls, "Value 2 should remain cancelled")
|
||||
require.Equal(t, []int{1, 3, 1}, calls, "Value 2 should remain cancelled")
|
||||
}
|
||||
|
||||
func TestWatchdogDelayBackwardCompatibility(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue