-
-
Notifications
You must be signed in to change notification settings - Fork 454
feat(quinn): Pass in &mut self
for AsyncUdpSocket
's poll_recv
and re-introduce poll_send
#2259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
8e11fe1
to
86f4953
Compare
When manually setting
(this is a comparison between The other benchmark is very similar as well (but much noisier!).
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I think this is a good direction overall, though we may want to delay merging somewhat as it's breaking.
I see no reason to expect that these changes present any performance hazard, and I'm satisfied with the smoke-testing you've done to check that assumption. |
814245c
to
8bea58b
Compare
…pSocket` in connections
…recv` take `&mut self`
8bea58b
to
51559ee
Compare
Just to spell it out: I think I've addressed all reviewing concerns, and I think we're waiting only for the right moment to merge these breaking changes? I realized I might be wrong though, given you're only saying "good direction" and requesting changes, so I'm double-checking now. |
That matches my understanding. We want to get a release out before we start merging incompatible changes. |
This PR contains some changes to the
AsyncUdpSocket
trait. In short:poll_recv
now takes&mut self
instead of&self
try_send
is removed fromAsyncUdpSocket
create_io_poller
and theUdpPoller
trait are now replaced withcreate_sender
and theUdpSender
traitUdpSender
trait has atry_send
as well as apoll_send
function (that takesself: Pin<&mut Self>
) instead of apoll_writable
functionThe final traits look like this:
Motivation
The general idea is to encode the invariants that the runtime and socket implementations need to adhere to into rust's type system.
One of the harder things for me was to understand initially when I was working with quinn's
AsyncUdpSocket
was when you're allowed to overwrite the waker you're getting frompoll_recv
and when you can't, and similarly for the oldUdpPoller
.Also, with iroh we had annoying issues with passing state from
poll_writable
totry_send
. With a singlepoll_send
that gives you (essentially)&mut self
access, this gets much easier.With all of these changes it's also a lot clearer when it's fine to overwrite wakers in your custom implementation. If
&mut self
is passed in from yourpoll
function, then you know you can only be called from a single task that owns you at a time, thus you can safely overwrite old wakers (and even do so without any use of mutexes or fancy linked lists or anything like that).Performance
I've tried testing the performance of this on various systems (my laptop, dedicated bare metal servers, etc.). I wasn't able to determine any differences, but at the same time, I always got very inconsistent results (both on quinn
main
and this PR).I'd really appreciate any help from someone who knows how to benchmark quinn effectively. There's some more things I can try, such as fiddling with the constants mentioned in #1126, but other than that I'm out of ideas.
Looking at the code, this should not have a negative performance impact. I think there's technically 1 more Arc clone for initiating connections, but other than that it should result in pretty much the same amount of work/same sequence of syscalls.