net/sockstats: wait before reporting battery usage

Wait 2 minutes before we start reporting battery usage. There is always
radio activity on initial startup, which gets reported as 100% high
power usage.  Let that settle before we report usage data.

Updates tailscale/corp#9230

Signed-off-by: Will Norris <will@tailscale.com>
pull/8108/head
Will Norris 2 years ago committed by Will Norris
parent 1ce08256c0
commit ea84fc9ad2

@ -325,6 +325,10 @@ type radioMonitor struct {
// Usage is measured once per second, so this is the number of seconds of history to track. // Usage is measured once per second, so this is the number of seconds of history to track.
const radioSampleSize = 3600 // 1 hour const radioSampleSize = 3600 // 1 hour
// initStallPeriod is the minimum amount of time in seconds to collect data before reporting.
// Otherwise, all clients will report 100% radio usage on startup.
var initStallPeriod int64 = 120 // 2 minutes
var radio = &radioMonitor{ var radio = &radioMonitor{
now: time.Now, now: time.Now,
startTime: time.Now().Unix(), startTime: time.Now().Unix(),
@ -375,7 +379,7 @@ func (rm *radioMonitor) radioHighPercent() int64 {
} }
}) })
if periodLength == 0 { if periodLength < initStallPeriod {
return 0 return 0
} }
@ -386,7 +390,7 @@ func (rm *radioMonitor) radioHighPercent() int64 {
} }
// forEachSample calls f for each sample in the past hour (or less if less time // forEachSample calls f for each sample in the past hour (or less if less time
// has passed -- the evaluated period is returned) // has passed -- the evaluated period is returned, measured in seconds)
func (rm *radioMonitor) forEachSample(f func(c int, isActive bool)) (periodLength int64) { func (rm *radioMonitor) forEachSample(f func(c int, isActive bool)) (periodLength int64) {
now := rm.now().Unix() now := rm.now().Unix()
periodLength = radioSampleSize periodLength = radioSampleSize

@ -33,6 +33,14 @@ func TestRadioMonitor(t *testing.T) {
func(_ *testTime, _ *radioMonitor) {}, func(_ *testTime, _ *radioMonitor) {},
0, 0,
}, },
{
"active less than init stall period",
func(tt *testTime, rm *radioMonitor) {
rm.active()
tt.Add(1 * time.Second)
},
0, // radio on, but not long enough to report data
},
{ {
"active, 10 sec idle", "active, 10 sec idle",
func(tt *testTime, rm *radioMonitor) { func(tt *testTime, rm *radioMonitor) {
@ -42,13 +50,13 @@ func TestRadioMonitor(t *testing.T) {
50, // radio on 5 seconds of 10 seconds 50, // radio on 5 seconds of 10 seconds
}, },
{ {
"active, spanning two seconds", "active, spanning three seconds",
func(tt *testTime, rm *radioMonitor) { func(tt *testTime, rm *radioMonitor) {
rm.active() rm.active()
tt.Add(1100 * time.Millisecond) tt.Add(2100 * time.Millisecond)
rm.active() rm.active()
}, },
100, // radio on for 2 seconds 100, // radio on for 3 seconds
}, },
{ {
"400 iterations: 2 sec active, 1 min idle", "400 iterations: 2 sec active, 1 min idle",
@ -66,13 +74,17 @@ func TestRadioMonitor(t *testing.T) {
{ {
"activity at end of time window", "activity at end of time window",
func(tt *testTime, rm *radioMonitor) { func(tt *testTime, rm *radioMonitor) {
tt.Add(1 * time.Second) tt.Add(3 * time.Second)
rm.active() rm.active()
}, },
50, 25,
}, },
} }
oldStallPeriod := initStallPeriod
initStallPeriod = 3
t.Cleanup(func() { initStallPeriod = oldStallPeriod })
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
tm := &testTime{time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)} tm := &testTime{time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)}

Loading…
Cancel
Save