Reduce device freeze on large TCP hubs, reduce announce processing overhead

This commit is contained in:
DeFiDude
2026-03-28 21:11:31 -06:00
parent 59200d6aea
commit 9e4217085a
5 changed files with 14 additions and 9 deletions

View File

@@ -50,7 +50,7 @@
#define RATDECK_MAX_ANNOUNCES_PER_SEC 5 // Transport-level rate limit (before Ed25519 verify)
// --- Limits ---
#define RATDECK_MAX_NODES 200 // PSRAM allows more
#define RATDECK_MAX_NODES 100 // Endpoint device, not transport node
#define RATDECK_MAX_MESSAGES_PER_CONV 100
#define FLASH_MSG_CACHE_LIMIT 20
#define RATDECK_MAX_OUTQUEUE 20

View File

@@ -985,6 +985,11 @@ void loop() {
}
}
// 4.5 Keep LVGL responsive after heavy RNS processing (announce floods)
if (rnsDuration > LVGL_INTERVAL_MS && powerMgr.isScreenOn()) {
lv_timer_handler();
}
// 5. Auto-announce every 5-360 minutes (user configured)
const unsigned long announceInterval = (unsigned long)userConfig.settings().announceInterval * 60000; // m -> ms
if (bootComplete && millis() - lastAutoAnnounce >= announceInterval) {

View File

@@ -154,13 +154,13 @@ void AnnounceManager::received_announce(
if (!name.empty()) node.name = name;
if (!idHex.empty()) node.identityHex = idHex;
node.lastSeen = now;
node.hops = RNS::Transport::hops_to(destination_hash);
// hops_to() is expensive (linear routing table scan) — only call for saved contacts
if (node.saved) node.hops = RNS::Transport::hops_to(destination_hash);
if (_loraIf) { node.rssi = _loraIf->lastRxRssi(); node.snr = _loraIf->lastRxSnr(); }
if (node.saved) _contactsDirty = true;
// Only compute toHex for log + name cache when node actually updated
std::string destHex = destination_hash.toHex();
Serial.printf("[ANNOUNCE] Update: %s name=\"%s\"\n", destHex.c_str(), name.c_str());
// Name cache update — skip expensive toHex() for unnamed re-announces
if (!name.empty()) {
std::string destHex = destination_hash.toHex();
auto nc = _nameCache.find(destHex);
if (nc == _nameCache.end() || nc->second != name) {
_nameCache[destHex] = name;
@@ -229,7 +229,7 @@ void AnnounceManager::received_announce(
node.name = name.empty() ? destHex.substr(0, 12) : name;
node.identityHex = idHex;
node.lastSeen = millis();
node.hops = RNS::Transport::hops_to(destination_hash);
// Skip hops_to() for new (unsaved) nodes — resolved when added as contact
if (_loraIf) { node.rssi = _loraIf->lastRxRssi(); node.snr = _loraIf->lastRxSnr(); }
_hashIndex[key] = (int)_nodes.size();
_nodes.push_back(node);

View File

@@ -73,7 +73,7 @@ private:
unsigned long _globalAnnounceWindowStart = 0;
unsigned int _globalAnnounceCount = 0;
static constexpr unsigned int MAX_GLOBAL_ANNOUNCES_PER_SEC = 10;
static constexpr int MAX_NODES = 200;
static constexpr int MAX_NODES = 100;
static constexpr int MAX_NAME_CACHE = 300;
static constexpr unsigned long CONTACT_SAVE_INTERVAL_MS = 30000;
static constexpr unsigned long ANNOUNCE_MIN_INTERVAL_MS = 200; // Rate-limit announce processing

View File

@@ -83,9 +83,9 @@ void TCPClientInterface::loop() {
return; // Will reconnect on next loop iteration
}
// Drain multiple incoming frames per loop (up to 15, time-boxed)
// Drain incoming frames per loop (up to 5, time-boxed to prevent announce flood blocking)
unsigned long tcpStart = millis();
for (int i = 0; i < 15 && _client.available() && (millis() - tcpStart < TCP_LOOP_BUDGET_MS); i++) {
for (int i = 0; i < 5 && _client.available() && (millis() - tcpStart < TCP_LOOP_BUDGET_MS); i++) {
unsigned long rxStart = millis();
int len = readFrame();
if (len > 0) {