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

Remove tokio-codec dependency from multistream-select. #1203

Merged
merged 5 commits into from
Jul 29, 2019

Conversation

romanb
Copy link
Contributor

@romanb romanb commented Jul 16, 2019

In preparation for the eventual switch from tokio to std futures, this PR removes the tokio-codec dependency from multistream-select. This includes some initial refactoring / cleanup in preparation for further work on multistream-select in the larger context of #659 - I'm just trying to work in small(er) increments to make the changes more digestible.

@romanb romanb force-pushed the multiselect-part-1 branch 2 times, most recently from e59f485 to a44d218 Compare July 17, 2019 12:43
Roman S. Borschel added 5 commits July 25, 2019 12:01
In preparation for the eventual switch from tokio to std futures.

Includes some initial refactoring in preparation for further work
in the context of libp2p#659.
Copy link
Member

@tomaka tomaka left a comment

Choose a reason for hiding this comment

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

Looks good, but I'm curious about the start_withs(b"/")

let mut msg = BytesMut::new();
request.encode(&mut msg)?;
match self.inner.start_send(msg.freeze())? {
AsyncSink::NotReady(_) => Ok(AsyncSink::NotReady(request)),
Copy link
Member

Choose a reason for hiding this comment

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

Not great for performances that we're dropping the encoded message if the socket is not ready, but this will no longer be a problem with new futures, so I'm ok ignoring that.

Copy link
Member

Choose a reason for hiding this comment

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

For what it's worth, in new futures you have to wait for the Sink to be ready before calling start_send. Calling start_send is then guaranteed to never fail for readiness-related reasons.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just curious: with the current futures, do you see a better way for the general case of wanting to nest Sinks with different item types (due to being different layers of abstraction) while avoiding the re-encoding from the upper to the lower-level item type? I guess if the encoding would be expensive, an additional buffer of encoded messages could do? In any case, I obviously didn't think this an important issue here since the encoding is presumably cheap and from my understanding typically at most done twice for 1 out of N > 1 messages, assuming the sinks can generally buffer quite a few messages to send before being NotReady. Good to see though that this seems to be a non-issue in the newer futures API.

Copy link
Member

Choose a reason for hiding this comment

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

with the current futures, do you see a better way for the general case of wanting to nest Sinks with different item types (due to being different layers of abstraction) while avoiding the re-encoding from the upper to the lower-level item type?

I don't think so. That's presumably why it has been changed in new futures.

fn encode(&self, dest: &mut BytesMut) -> Result<(), MultistreamSelectError> {
match self {
Request::Protocol { name } => {
if !name.as_ref().starts_with(b"/") {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not aware of this rule! Do protocol names have to start with /?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, strictly speaking no, it is just a convention, the "spec" says

[..] While any string can be used, the conventional format is a path-like structure containing a short name and a version number, separated by / characters. [..]

but it doesn't even bother saying what a "string" here is in terms of encoding, so it sounds like a sentence quickly extrapolated from a go or js implementation. Practically, the requirement for the leading / did not change in this PR - this "restriction" was already there and is needed for decoding. Personally, I'm very much in favor of stricter parsing of protocol names reflecting the "conventional format", based on a simple grammar (e.g. a protocol name must start with a /, followed by a sequence of alphanumeric strings including dots and hyphens, separated by /).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

[..] While any string can be used, the conventional format is a path-like structure containing a short name and a version number, separated by / characters. [..]

but it doesn't even bother saying what a "string" here is in terms of encoding

I stand corrected, it does state further down that

Messages are sent encoded as UTF-8 byte strings, [..]

which implies utf-8 encoding for protocol names. This is unfortunately also not enforced by this implementation since the interface rests on AsRef<[u8]>.

@romanb romanb merged commit 2fd9411 into libp2p:master Jul 29, 2019
@romanb romanb deleted the multiselect-part-1 branch July 29, 2019 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants