-
Notifications
You must be signed in to change notification settings - Fork 961
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
core/muxing: Flatten StreamMuxer
interface to poll_{inbound,outbound,address_change,close}
#2724
Conversation
StreamMuxer
.StreamMuxer
c2106db
to
a28a7c5
Compare
cd4d01a
to
a2c64ae
Compare
Rebased to stay on top of #2710. |
Appreciate the elaborate pull request! Still have to give this more thought. As you mentioned in #2648, given that we don't have a muxer with backpressure on stream creation today (e.g. QUIC), we will likely not do a good job designing this abstraction at this point in time. For now, we could get rid of Again, have to think about it some more. |
If somehow possible, I'd like to get rid of this ID because it is actually unnecessarily complicated. Without this ID, we can drop abstractions like There is nothing special about a substream that requires us to do this explicit book-keeping. All we need is a mechanism for the caller to say: I want a new one. I started with a simple |
This variant is not yet constructed but we will need it very soon.
It is easier for clients to only call one poll function that can be configured, which substreams to open. This API change is also trying to plan ahead for muxers like QUIC which actually allow to only open substreams in one direction.
It is unused.
a2c64ae
to
3c3bed3
Compare
Clean rebase onto master, no changes other than dropping commits of previous parent PR. |
I just had what I think is a really good idea! Instead of having a |
@@ -1,13 +1,14 @@ | |||
# 0.34.0 - unreleased | |||
|
|||
- Introduce `StreamMuxerEvent::map_inbound_stream`. See [PR 2691]. |
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.
I deleted this changelog entry because it is not released yet and it no longer makes any sense if the entire type is gone now!
Yep that is what I thought too! Exposing individual knobs has a lot more flexibility. I do want to try and build a wrapper around this with different trade-offs, i.e. "simpler API, less knobs".
No rush. I am away from my laptop for the next week or so anyway :) |
handler: wrapped_handler, | ||
open_info: VecDeque::with_capacity(8), |
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.
This replaces a SmallVec
from Muxing
to ensure that we use the OpenInfo
in a FIFO manner. A capacity of 8 at least makes only one allocation and thus, the (unbenchmarked) performance profile should be similar.
Open to better ideas.
swarm/src/connection.rs
Outdated
if let Poll::Ready(substream) = self.muxing.poll_inbound(cx)? { | ||
self.handler | ||
.inject_substream(substream, SubstreamEndpoint::Listener); | ||
continue; | ||
} | ||
|
||
if let Poll::Ready(address) = self.muxing.poll_address_change(cx)? { | ||
self.handler.inject_address_change(&address); | ||
return Poll::Ready(Ok(Event::AddressChange(address))); | ||
} |
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.
I think it makes sense to flip these.
Did you get a chance to look at this @mxinden ? |
I think we should do this change 👍 As far as I can tell, the QUIC implementation would be easy to adapt: Can we prevent users (not implementors) forgetting to call one of the I suggest we wait for #2289 and #2622 to adapt to the latest //CC @elenaf9 and @kpp for #2289 and //CC @melekes for #2622 |
I don't think it is possible. We might be able to provide a wrapper struct but I see |
Hmm, I'd prefer to merge this early to be honest. Happy to wait for an assessment from @kpp, @elenaf9 and @melekes whether merging first would make things easier. |
How does the new interface translates when it comes to type OutboundSubstream = BoxFuture<'static, Result<Arc<DetachedDataChannel>, Self::Error>>; In webrtc transport, I create a future in |
The new interface provides a If your implementation is based on async, you'd probably want to have an |
Currently, this interface still relies on internal mutability but I am planning to make it |
Fine by me as well. Mind resolving the conflicts @thomaseizinger? |
Conflicts resolved. Please check if I updated the changelog and manifest versions correctly @mxinden ! |
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 for the thorough work! Great to have you here.
Poll::Ready(SubstreamEvent::AddressChange(address)) => { | ||
self.handler.inject_address_change(&address); | ||
return Poll::Ready(Ok(Event::AddressChange(address))); | ||
continue; // Go back to the top, handler can potentially make progress again. |
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.
Side note, I like this style of:
- When one made progress
- but one does not return
- start from the top via
continue
as other sub components might be able to make progress now.
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.
I do too although it is a pattern I had to get used to and it is not trivial to understand when you get started with async Rust.
Follow up on libp2p#2724. Given that libp2p-core is bumped to v0.35.0, libp2p-tcp needs to be bumped as well.
Follow up on #2724. Given that libp2p-core is bumped to v0.35.0, libp2p-tcp needs to be bumped as well.
Discussed in libp2p#2722.
…nd,address_change,close}` (libp2p#2724) Instead of having a mix of `poll_event`, `poll_outbound` and `poll_close`, we flatten the entire interface of `StreamMuxer` into 4 individual functions: - `poll_inbound` - `poll_outbound` - `poll_address_change` - `poll_close` This design is closer to the design of other async traits like `AsyncRead` and `AsyncWrite`. It also allows us to delete the `StreamMuxerEvent`.
Description
This is the next changeset on our journey to #2722!
Instead of having a mix of
poll_event
,poll_outbound
andpoll_close
, we flatten the entire interface ofStreamMuxer
into 4 individual functions:poll_inbound
poll_outbound
poll_address_change
poll_close
This design is closer to the design of other async traits like
AsyncRead
andAsyncWrite
. It also allows us to delete theStreamMuxerEvent
.Links to any relevant issues
Part of #2722.
Open Questions
Change checklist
I have added tests that prove my fix is effective or that my feature works