You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AsyncUdpSocket::poll_recv multiplexes receiving datagrams from 3 different sources:
IPv4 UDP socket
IPv6 UDP socket
Relay channel
Currently they are polled in this specific order: first IPv4, only if that returns Pending poll IPv6 and only if also that returns Pending does it poll the relay channel. If one of the polls returns Ready the remaining ones are not polled.
This unfairly penalises the relay channel.
A possible solution is for the MagicSock to have buffers for datagrams that are ready. Whenever there is something in the buffers return it as Poll::Ready without polling any of the sources. If the buffers are empty always poll all the sources and store any Ready results that are not immediately returned in a buffer.
## Description
The existing AsyncUdpSocket::poll_recv polled the UDP IPv4 socket
first, only if that has no datagrams would it poll UDP IPv6 and only
also that had no datagrams to deliver was the relay socket polled.
This highly favoured IPv4 relay traffic, potentially starving the
relay traffic.
This change makes it prefer a different source on each poll. Meaning
if multiple sockets have data to deliver a fairer delivery happens.
Closes#2981.
## Breaking Changes
<!-- Optional, if there are any breaking changes document them,
including how to migrate older code. -->
## Notes & open questions
- Using Ordering::Relaxed is probably fine. I believe normally
this polling would only happen from a single task (the Quinn
endpoint driver) and even if it was polled concurrently from
different threads it would not be that bad and still an improvement
on the current order.
- I'm not particularly fond of the implementation, but the macros is
the best I could come up with. Maybe there's something cleverer
which can be done.
## Change checklist
- [x] Self-review.
- [x] Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.
- [x] Tests if relevant.
- [x] All breaking changes documented.
---------
Co-authored-by: Philipp Krüger <[email protected]>
AsyncUdpSocket::poll_recv
multiplexes receiving datagrams from 3 different sources:Currently they are polled in this specific order: first IPv4, only if that returns
Pending
poll IPv6 and only if also that returnsPending
does it poll the relay channel. If one of the polls returnsReady
the remaining ones are not polled.This unfairly penalises the relay channel.
A possible solution is for the MagicSock to have buffers for datagrams that are ready. Whenever there is something in the buffers return it as
Poll::Ready
without polling any of the sources. If the buffers are empty always poll all the sources and store anyReady
results that are not immediately returned in a buffer.This is one of the issues found from #2951.
The text was updated successfully, but these errors were encountered: