mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-08-28 05:54:19 +00:00
fix: poller uses store max IDs to prevent replaying entire DB
When GetMaxTransmissionID() fails silently (e.g., corrupted DB returns 0 from COALESCE), the poller starts from ID 0 and replays the entire database over WebSocket — broadcasting thousands of old packets per second. Fix: after querying the DB, use the in-memory store's MaxTransmissionID and MaxObservationID as a floor. Since Load() already read the full DB successfully, the store has the correct max IDs. Root cause discovered on staging: DB corruption caused MAX(id) query to fail, returning 0. Poller log showed 'starting from transmission ID 0' followed by 1000-2000 broadcasts per tick walking through 76K rows. Also adds MaxObservationID() to PacketStore for observation cursor safety. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1344,6 +1344,20 @@ func (s *PacketStore) MaxTransmissionID() int {
|
||||
return maxID
|
||||
}
|
||||
|
||||
// MaxObservationID returns the highest observation ID in the store.
|
||||
func (s *PacketStore) MaxObservationID() int {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
maxID := 0
|
||||
for id := range s.byObsID {
|
||||
if id > maxID {
|
||||
maxID = id
|
||||
}
|
||||
}
|
||||
return maxID
|
||||
}
|
||||
|
||||
// --- Internal filter/query helpers ---
|
||||
|
||||
// filterPackets applies PacketQuery filters to the in-memory packet list.
|
||||
|
||||
@@ -166,6 +166,17 @@ func NewPoller(db *DB, hub *Hub, interval time.Duration) *Poller {
|
||||
func (p *Poller) Start() {
|
||||
lastID := p.db.GetMaxTransmissionID()
|
||||
lastObsID := p.db.GetMaxObservationID()
|
||||
// If the store already loaded data, use its max IDs as a floor.
|
||||
// This prevents replaying the entire DB when the DB query fails
|
||||
// (e.g., corrupted DB returns 0 from COALESCE).
|
||||
if p.store != nil {
|
||||
if storeMax := p.store.MaxTransmissionID(); storeMax > lastID {
|
||||
lastID = storeMax
|
||||
}
|
||||
if storeMaxObs := p.store.MaxObservationID(); storeMaxObs > lastObsID {
|
||||
lastObsID = storeMaxObs
|
||||
}
|
||||
}
|
||||
log.Printf("[poller] starting from transmission ID %d, obs ID %d, interval %v", lastID, lastObsID, p.interval)
|
||||
|
||||
ticker := time.NewTicker(p.interval)
|
||||
|
||||
Reference in New Issue
Block a user