fix(mesh): avoid tx delay build up with setTransmitDelay#9780
fix(mesh): avoid tx delay build up with setTransmitDelay#9780m1nl wants to merge 3 commits intomeshtastic:developfrom
Conversation
setTransmitDelay increases delay for the very first packet in tx queue. Current implementation calls setTransmitDelay whenever TX or RX interrupt is received or canSendImmediately is false. In setTransmitDelay when tx_after is set, it will be always increased by add_delay which makes the value build up in busy environments very quickly.
There was a problem hiding this comment.
Pull request overview
Adjusts setTransmitDelay() to prevent transmission delay (tx_after) from compounding on frequent interrupts, avoiding excessive TX backoff in busy environments.
Changes:
- Updates
tx_aftercomputation to avoid addingadd_delayrepeatedly whentx_afteris already set.
|
Note that It was mostly done this way in order for Besides, when |
Thanks for feedback! At the moment when |
This is not the case. When you receive/transmit a packet, the I'm also curious how @erayd thinks of this. |
I think the other argument in p->tx_after = min(max((unsigned long)p->tx_after, now + add_delay), now + 2 * getTxDelayMsecWeightedWorst(p->rx_snr));In general, I think my change can be summarized as follows: Once the initial |
|
I performed some testing to show what is the case I'm referring to. Please take a look at traces below. When a packet with This also breaks ordering and makes the packet with much higher tx_after be in front of packets, which are heavily late. Actually we could consider sorting the queue, whenever |
|
I do see what you mean and while I still think the original way was the most "correct" in terms of the intended behaviour of Still I would like to hear what @erayd thinks of this. |
|
I missed your first tag sorry @GUVWAF - am flat out right now, but should get to this later today. It's supposed to be clamped to something sane, so if the time is blowing out massively I'd consider that a bug (possibly interrupt / notification related, if it's firing the increase before tx_after is reached). I'll have a good look though the logic again, as it's been a while since I touched this part of the code. @m1nl What was ChUtil on that node doing during your logged tests? If it's getting stuck with delayed packets in the queue, that may mean utilisation is getting too high and it's simply struggling to find some space to transmit where other nodes aren't already using the frequency. "Somebody else is talking" should result in it adding a small additional delay (in any mode, not just ROUTER_LATE) and then trying again. Not really related to this PR I think, but a better structure for the TX queue would IMO be a good idea. I think we're trying to make the current one do too many things at once, and the data structure used isn't particularly well suited to it any more. |
setTransmitDelayincreases the delay of the first packet in the TX queue. In the current implementation,setTransmitDelayis called whenever a TX or RX interrupt is received, or whencanSendImmediately()returns false.When
tx_afteris set, each call tosetTransmitDelayincreases it further byadd_delay. In busy environments, where interrupts occur frequently, this causestx_afterto grow rapidly, resulting in excessive transmission delays.My PR prevents
tx_afterfrom being increased on every call tosetTransmitDelay. It is also worth noting that existing logic prevents packets from being sent immediately, sincemaxwill selectnow + add_delayif it is greater thantx_after: