fix(filter): suppress health-check pings in background mode

FilterHealthCheckLoop fires every 1 min and sends a Waku protocol ping
to each subscribed filter peer. On Android, these pings queue up during
Doze and flush in maintenance windows (~15 min), keeping the LTE modem
at ~55-58% duty cycle even when the app is backgrounded.

This was the dominant radio wakeup source missed by the previous commit
(which only gated subscription renewal in subscriptionLoop). mag's
measurement on #21111 confirmed modem still 58% active post-R1.

Add backgroundMode atomic.Bool to WakuFilterLightNode with a
SetBackgroundMode(bool) method. FilterHealthCheckLoop skips PingPeers()
when backgrounded. FilterManager.SetBackgroundMode now cascades to both
layers: subscription renewal (api/filter) and health-check pings
(protocol/filter).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Alisher 2026-06-03 08:09:40 +02:00
parent ab4609ef15
commit 9f8361930d
3 changed files with 17 additions and 0 deletions

View File

@ -197,9 +197,12 @@ func (mgr *FilterManager) NetworkChange() {
func (mgr *FilterManager) SetBackgroundMode(background bool) {
mgr.Lock()
defer mgr.Unlock()
// Gate subscription renewal (api/filter layer)
for _, subDetails := range mgr.filterSubscriptions {
subDetails.sub.SetBackgroundMode(background)
}
// Gate health-check pings (protocol/filter layer) — the dominant LTE radio wakeup source
mgr.node.SetBackgroundMode(background)
}
// checkAndProcessQueue drains the offline-pending filter queue. For each batch

View File

@ -8,6 +8,7 @@ import (
"math"
"net/http"
"sync"
"sync/atomic"
"time"
"github.com/libp2p/go-libp2p/core/host"
@ -57,6 +58,7 @@ type WakuFilterLightNode struct {
pm *peermanager.PeerManager
limiter *utils.RateLimiter
peerPingInterval time.Duration
backgroundMode atomic.Bool // true when app UI is not visible; suppresses health-check pings
}
type WakuFilterPushError struct {

View File

@ -42,6 +42,13 @@ func (wf *WakuFilterLightNode) PingPeer(peer peer.ID) {
}
}
// SetBackgroundMode suppresses (background=true) or re-enables (background=false)
// the periodic health-check pings sent to filter peers. Call with background=true
// when the app UI is not visible to avoid waking the LTE radio during Doze windows.
func (wf *WakuFilterLightNode) SetBackgroundMode(background bool) {
wf.backgroundMode.Store(background)
}
func (wf *WakuFilterLightNode) FilterHealthCheckLoop() {
defer utils.LogOnPanic()
defer wf.WaitGroup().Done()
@ -50,6 +57,11 @@ func (wf *WakuFilterLightNode) FilterHealthCheckLoop() {
for {
select {
case <-ticker.C:
if wf.backgroundMode.Load() {
// In background: skip health-check ping to avoid waking the LTE radio.
// SetBackgroundMode(false) will resume pings on foreground return.
continue
}
if wf.onlineChecker.IsOnline() {
wf.PingPeers()
}