From 0c515d45fe91ba5ee01b1a3567f0e77c09353cf8 Mon Sep 17 00:00:00 2001 From: Walter Boring Date: Wed, 13 May 2026 12:14:21 -0400 Subject: [PATCH] fix: filter stale BeaconPackets from PacketTrack on load from disk Older versions persisted BeaconPackets to packettrack.json. On restart these zombie beacons would be retransmitted by the scheduler. Now PacketTrack.load() strips any BeaconPackets from the persisted data. Workaround: delete ~/.config/aprsd/packettrack.json before restarting. --- aprsd/packets/tracker.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/aprsd/packets/tracker.py b/aprsd/packets/tracker.py index 15fa3b8..32cbeab 100644 --- a/aprsd/packets/tracker.py +++ b/aprsd/packets/tracker.py @@ -114,6 +114,29 @@ class PacketTrack(objectstore.ObjectStoreMixin): def remove(self, key): self._remove(key) + def load(self): + """Load tracked packets from disk, filtering out stale BeaconPackets. + + BeaconPackets should never be retried (they are fire-and-forget), + but older versions persisted them to disk. Strip them on load so + they don't get retransmitted after a restart. + """ + super().load() + with self.lock: + stale = [ + key + for key, pkt in self.data.items() + if isinstance(pkt, core.BeaconPacket) + or (isinstance(pkt, dict) and pkt.get('_type') == 'BeaconPacket') + ] + for key in stale: + del self.data[key] + if stale: + LOG.info( + f'PacketTrack: removed {len(stale)} stale BeaconPacket(s) ' + f'from persisted data.', + ) + def _remove(self, key): with self.lock: try: