mirror of
https://github.com/kerberos-io/onvif.git
synced 2026-08-23 15:08:33 +00:00
The previous 30-second cap meant a 1000-camera fleet recovering from a switch reboot would generate a sustained 33 RPS of doomed CreatePullPointSubscription traffic against still-booting cameras, and the synchronised retries would arrive in phase. Two changes: * Cap raised to 5 minutes. Single-camera recovery latency goes from '<=30s after camera comes back' to '<=300s', which is fine because by the time we are this deep in backoff the camera has already been unreachable through 6+ attempts (1s, 2s, 4s, 8s, 16s, 30s under the old cap) — the marginal recovery delay is acceptable to avoid the network melt. * Symmetric ±25% jitter on every recreate sleep so synchronised drops (switch reboot, DHCP storm, NTP slew) do not cause synchronised reconnect surges. Standard practice — same shape AWS, Cloudflare and HA event_manager use. Tests assert the jitter range, the documented cap value (so a future maintainer flipping it back to 30s notices in CI), and that jitter varies across calls (proves the rand source is wired).
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package stream
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestJitter_StaysWithinFraction(t *testing.T) {
|
|
const base = time.Second
|
|
low := time.Duration(float64(base) * (1 - jitterFraction))
|
|
high := time.Duration(float64(base) * (1 + jitterFraction))
|
|
for i := 0; i < 200; i++ {
|
|
got := jitter(base)
|
|
assert.GreaterOrEqual(t, got, low, "iteration %d", i)
|
|
assert.LessOrEqual(t, got, high, "iteration %d", i)
|
|
}
|
|
}
|
|
|
|
func TestJitter_ZeroAndNegativeReturnPositive(t *testing.T) {
|
|
assert.Greater(t, jitter(0), time.Duration(0))
|
|
assert.Greater(t, jitter(-time.Second), time.Duration(0))
|
|
}
|
|
|
|
func TestJitter_VariesAcrossCalls(t *testing.T) {
|
|
// Sanity check that we're not returning a constant. Vanishingly
|
|
// unlikely to flake (probability ~ (1/uint64-space)^9).
|
|
first := jitter(time.Second)
|
|
allEqual := true
|
|
for i := 0; i < 10; i++ {
|
|
if jitter(time.Second) != first {
|
|
allEqual = false
|
|
break
|
|
}
|
|
}
|
|
assert.False(t, allEqual, "jitter is producing a constant; rand seed not working")
|
|
}
|
|
|
|
func TestMaxRecreateBackoff_Is5Minutes(t *testing.T) {
|
|
// Document the policy choice in a test so a future maintainer
|
|
// changing this notices.
|
|
assert.Equal(t, 5*time.Minute, maxRecreateBackoff)
|
|
}
|