Skip to content
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

Refactor UdpMuxNewAddr to be lock-less #1

Merged
merged 24 commits into from
Aug 31, 2022

Conversation

thomaseizinger
Copy link

@thomaseizinger thomaseizinger commented Aug 2, 2022

TBD

The general idea is this:

We use `flume` channels between the actual `UdpMuxNewAddr` instance
and a set of "handles", one per async-trait that we need to satisfy.

There is only one instance of `UdpMuxNewAddr`, meaning we can access
it via `&mut self` and drop all locks within it.

In the poll function, we can then decide, which events to prioritise
over others. Most importantly, all channels between handles and the
actual instance are "rendezvous channels", meaning, sending will block
until we actually read the item out of the channel. This allows us
to enforce backpressure from the poll function all the way to all
handles and into the task that is interacting with the handle.
Copy link

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

I am in favor of this design, namely a single UdpMuxNewAddr, connected to all remaining components via channels.

If I am not mistaken with the current state of this pull request UdpMuxNewAddr would be driven by WebRTCListenStream, which is driven by Transport::poll, which is driven by the main libp2p event loop, making the whole execution in some sense single threaded. I don't think this needs to be tackled right away. We can fix this similar to QUIC via a single task per UdpMuxNewAddr or a single task per WebRTCTransport.

transports/webrtc/Cargo.toml Outdated Show resolved Hide resolved
@thomaseizinger
Copy link
Author

Can I get another high-level review please? @mxinden @melekes

@@ -0,0 +1,49 @@
use futures::channel::mpsc;
Copy link

Choose a reason for hiding this comment

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

Missing license header. Feel free to ignore.

Copy link
Author

Choose a reason for hiding this comment

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

Can I? I'd love to get rid of those 😅

Copy link

Choose a reason for hiding this comment

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

Haha, I meant "Feel free to ignore [for now]".

I think we should be consistent in this pull request.

I am fine getting rid of them in general, though I would need to check back with some legal experts first.

transports/webrtc/src/req_res_chan.rs Show resolved Hide resolved
@mxinden
Copy link

mxinden commented Aug 9, 2022

On the meta level, thanks @thomaseizinger for writing this PoC. Especially the recent version reads very cleanly.

@mxinden
Copy link

mxinden commented Aug 10, 2022

Overall I am in favor of this architectural change. I hope for this to resolve issues like libp2p#2622 (comment) and libp2p#2622 (comment).

@melekes do I understand correctly that you still favor the Mutex approach? If so, please give us another chance to lay out our arguments for this alternative approach.

@thomaseizinger
Copy link
Author

@mxinden Another review would be appreciated! I think the refactoring is now functionally complete.

Two tests are hanging but they also hang on @melekes 's latest version of the webrtc-transport branch so I am not quite sure what to do about that.

@thomaseizinger thomaseizinger changed the title Dirty PoC for lock-less UdpMuxNewAddr Refactor UdpMuxNewAddr to be lock-less Aug 18, 2022
@thomaseizinger thomaseizinger marked this pull request as ready for review August 18, 2022 11:55
Copy link

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Thanks Thomas for the continued work here!

transports/webrtc/src/udp_mux.rs Outdated Show resolved Hide resolved
transports/webrtc/src/udp_mux.rs Outdated Show resolved Hide resolved
transports/webrtc/src/udp_mux.rs Outdated Show resolved Hide resolved
@thomaseizinger
Copy link
Author

I'd suggest to merge #3 first but apart from that, this is ready for a review @melekes @mxinden!

transports/webrtc/src/udp_mux.rs Outdated Show resolved Hide resolved
transports/webrtc/src/udp_mux.rs Outdated Show resolved Hide resolved
Instead of buffering multiple items, we only ever buffer one. To
work off this queue as quickly as possible, we put it at the top
of the loop which allows us to reduce some code duplication by
writing directly to the buffer in case we popped an item off the
queue and going back to the start of the loop which will trigger
a different code branch.
Copy link
Owner

@melekes melekes left a comment

Choose a reason for hiding this comment

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

nice work 👍

transports/webrtc/src/udp_mux.rs Show resolved Hide resolved
@melekes melekes merged commit 38175fd into melekes:anton/webrtc-transport Aug 31, 2022
@mxinden
Copy link

mxinden commented Aug 31, 2022

Thanks @thomaseizinger for the refactoring and thanks @melekes for merging.

@thomaseizinger thomaseizinger deleted the rewrite-udp-mux branch August 31, 2022 08:26
@thomaseizinger thomaseizinger mentioned this pull request Sep 1, 2022
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants