Skip to content

mesh: prioritize ACK/PATH/CONTROL in outbound scheduling#1957

Open
robekl wants to merge 1 commit intomeshcore-dev:devfrom
robekl:feature/ack-path-control-priority
Open

mesh: prioritize ACK/PATH/CONTROL in outbound scheduling#1957
robekl wants to merge 1 commit intomeshcore-dev:devfrom
robekl:feature/ack-path-control-priority

Conversation

@robekl
Copy link
Contributor

@robekl robekl commented Mar 7, 2026

Summary

This PR updates outbound packet scheduling priority in Mesh so reliability-critical traffic gets a consistent fast lane.

It prioritizes:

  • ACK first
  • PATH and CONTROL next
  • generic flood traffic after that
  • ADVERT lowest (unchanged intent)

New centralized priority helpers

Added internal helpers to classify priority by payload type:

  • local flood send priority
  • local direct send priority
  • flood retransmit priority

Behavior changes

Flood sends (sendFlood + transport variant)

  • ACK -> pri 0
  • PATH/CONTROL -> pri 1
  • generic flood -> pri 2
  • ADVERT -> pri 3

Direct sends (sendDirect, non-TRACE)

  • ACK/CONTROL -> pri 0
  • PATH -> pri 1
  • others -> pri 0
  • TRACE remains pri 5 (unchanged)

Flood retransmit scheduling (routeRecvPacket)

  • ACK -> pri 0
  • PATH/CONTROL -> pri 1
  • generic flood forced to at least pri 2 (max(2, path_hash_count)), preserving lower urgency than ACK/PATH/CONTROL

Why This Improves Current Implementation

Current implementation used mixed ad-hoc priority assignments (and hop-count-driven flood priority) that could let bulk flood traffic compete with reliability-critical control/feedback packets.

This change improves that by:

  • making ACK/PATH/CONTROL prioritization explicit and consistent
  • reducing queue delay for packets that stop retries and accelerate path convergence
  • preserving low urgency for adverts and non-critical flood traffic
  • keeping implementation low-risk (no queue data structure rewrite, no timing model rewrite)

Net Benefit

  • Faster ACK turnaround under load
  • Fewer retry cascades and fallback floods
  • Better path convergence/repair responsiveness
  • More deterministic scheduling behavior for critical traffic classes

Copy link
Contributor

@weebl2000 weebl2000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it. Let's test this. I think it makes sense.

Only thing to consider is if we might still want hop-count ordering for flood messages as a second priority.

@wbijen
Copy link
Contributor

wbijen commented Mar 8, 2026

Only thing to consider is if we might still want hop-count ordering for flood messages as a second priority.

It's already preserved right? The clamping is hop < 2 ? 2 : hop, so:
1 hop → pri 2
2 hops → pri 2 - has the same prio as 1 hop? might be better to bump
3 hops → pri 3
5 hops → pri 5

return packet->getPathHashCount() + 2;


EDIT:
looked at it more closely, the max(2, hop) src/Mesh.cpp:26 clamp creates a flat spot at hops 1–2:

Hops (n+1) max(2, n+1) n+1+1 n+1+2
1 2 2 3
2 2 3 4
3 3 4 5

getPathHashCount() + 1 preserves distinct hop-count ordering while keeping lanes 0–1 reserved. Might be a cleaner approach than the clamp.

@weebl2000
Copy link
Contributor

Yeah true. I think the ACK always having priority 0 is too high of a prio, we should mabye give 10 hop ack higher priority than 10, but I think 0 is too high. Perhaps hop count / 3 might be a good starting point. Same for PATH/control? Higher priority is good, but having everything highest priority can lead to abuse/unwanted congestion.

@wbijen
Copy link
Contributor

wbijen commented Mar 10, 2026

@weebl2000 My original comment was about an off-by-one bug in the code, I clarified it a bit so there is no more confusion. I think the proposal is still an improvement over the current status quo but your point is valid:

We could also do something like Hop-based offsets per type:

uint8_t hops = packet->getPathHashCount();
if (payload_type == PAYLOAD_TYPE_ACK) return hops;
if (payload_type == PAYLOAD_TYPE_PATH || payload_type == PAYLOAD_TYPE_CONTROL) return hops + 1;
return hops + 3;
Hops ACK (+0) PATH/CTRL (+1) Generic (+3)
1 1 2 4
2 2 3 5
3 3 4 6
  • Wider gap before generic (+3) gives control traffic room under load

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants