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

Restore RequestResponse::throttled. #1726

Merged
merged 20 commits into from
Sep 7, 2020
Merged

Restore RequestResponse::throttled. #1726

merged 20 commits into from
Sep 7, 2020

Conversation

twittner
Copy link
Contributor

@twittner twittner commented Sep 1, 2020

In contrast to the existing "throttled" approach this PR adds back-pressure to the protocol without requiring pre-existing knowledge of all node limits. It adds small, CBOR-encoded credit grant messages which communicate back to the sender how many more requests it is allowed to send.

Alternative to #1715.

In contrast to the existing "throttled" approach this PR adds back-
pressure to the protocol without requiring pre-existing knowledge
of all nodes about their limits. It adds small, CBOR-encoded headers
to the actual payload data. Extra credit messages communicate back
to the sender how many more requests it is allowed to send.
Should an error in some lower layer cause a connection to be closed,
our previously sent credit grant may not have reached the remote peer.
Therefore, pessimistically, a credit grant is resent whenever a
connection is closed. The remote ignores duplicate grants.
Copy link
Contributor

@romanb romanb left a comment

Choose a reason for hiding this comment

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

What do you think about moving the codec::header module to throttled::codec? I think it is conceivable that request-response may contain other auxiliary wrappers with their own headers in the future, so separating each into their own (sub)modules seems preferable.

protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/throttled.rs Outdated Show resolved Hide resolved
protocols/request-response/src/lib.rs Outdated Show resolved Hide resolved
protocols/request-response/src/codec/header.rs Outdated Show resolved Hide resolved
protocols/request-response/src/codec/header.rs Outdated Show resolved Hide resolved
twittner and others added 9 commits September 3, 2020 09:29
- Remove `ResponseSent` which was a leftover from previous attemps
  and issue a credit grant immediately in `send_response`.
- Only resend credit grants after a connection is closed if we are
  still connected to this peer.
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
@mxinden
Copy link
Member

mxinden commented Sep 4, 2020

As far as I know all of libp2p uses Protobuf for binary encoding. Can you explain what benefit is gained by encoding Header via cbor instead of Protobuf? Is this benefit worth the lost consistency across the project?

@twittner
Copy link
Contributor Author

twittner commented Sep 4, 2020

As far as I know all of libp2p uses Protobuf for binary encoding.

Mplex and yamux encode their headers in a custom format. Multi-addresses use another custom binary encoding. Peer IDs are multihashes, multistream-select uses length-prefixed and \n-terminated byte strings. And yes, other parts use protocol buffers.

Can you explain what benefit is gained by encoding Header via cbor instead of Protobuf?

Contrary to protocol buffers, CBOR is an IETF specification (RFC 7049) and not merely implementation defined. It is also rather lightweight w.r.t. tooling requirements. As you can see, there is no need for another compiler like protoc, no extra-language schema file, no build.rs. The full expressiveness of Rust can be used, e.g. generic types, sum types etc. without difficulties (but granted, Header in particular is not a complicated type). There is also no code generation that creates an extra set of types to match some schema language.

Is this benefit worth the lost consistency across the project?

I do not agree with this consistency claim which rests on a particular way to look at the various libp2p bits and pieces. From my perspective encodings are everywhere and nothing is lost by embracing this variety.

@mxinden
Copy link
Member

mxinden commented Sep 4, 2020

Mplex and yamux encode their headers in a custom format. Multi-addresses use another custom binary encoding. Peer IDs are multihashes, multistream-select uses length-prefixed and \n-terminated byte strings. And yes, other parts use protocol buffers.

I stand corrected! 🙂

Thanks for the detailed explanation @twittner. I would prefer to have a single generic binary encoding scheme just for the sake of reducing complexity. At the same time this opinion is not a strong one and should not block this pull request.

Since honest senders always assume a send budget of 1 and wait for
credit afterwards, setting the default limit to a higher value
can only become effective after informing the peer about it which
means leaving `max_recv` at 1 and setting `next_max` to the desired
value.
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.

3 participants