Просмотр исходного кода

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 <[email protected]>
Will Norris 2 лет назад
Родитель
Сommit
ea84fc9ad2
2 измененных файлов с 23 добавлено и 7 удалено
  1. 6 2
      net/sockstats/sockstats_tsgo.go
  2. 17 5
      net/sockstats/sockstats_tsgo_test.go

+ 6 - 2
net/sockstats/sockstats_tsgo.go

@@ -325,6 +325,10 @@ type radioMonitor struct {
 // Usage is measured once per second, so this is the number of seconds of history to track.
 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{
 	now:       time.Now,
 	startTime: time.Now().Unix(),
@@ -375,7 +379,7 @@ func (rm *radioMonitor) radioHighPercent() int64 {
 		}
 	})
 
-	if periodLength == 0 {
+	if periodLength < initStallPeriod {
 		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
-// 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) {
 	now := rm.now().Unix()
 	periodLength = radioSampleSize

+ 17 - 5
net/sockstats/sockstats_tsgo_test.go

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