Add Throttled to libp2p-request-response. (#1696)

* Use a single exchange instead of two one_shots.

* Add `Throttled` to libp2p-request-response.

Wraps the existing `RequestResponse` behaviour and applies strict limits
to the number of inbound and outbound requests per peer.

The wrapper is opt-in and if not used, the protocol behaviour of
`RequestResponse` does not change. This PR also does not introduce
an extra protocol, hence the limits applied need to be known a priori
for all nodes which is not always possible or desirable. As mentioned
in #1687 I think that we should eventually augment the protocol with
metadata which allows a more dynamic exchange of requests and responses.

This PR also replaces the two oneshot channels with a single one from the
scambio crate which saves one allocation per request/response. If not
desirable because the crate has seen less testing the first commit could
be reverted.

* Fix rustdoc error.

* Remove some leftovers from development.

* Add docs to `NetworBehaviourAction::{map_in,map_out}`.

* Apply suggestions from code review

Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>

* Add `ping_protocol_throttled` test.

* Add another test.

* Revert "Use a single exchange instead of two one_shots."

This reverts commit e34e1297d411298f6c69e238aa6c96e0b795d989.

# Conflicts:
#	protocols/request-response/Cargo.toml
#	protocols/request-response/src/handler/protocol.rs

* Update CHANGELOG.

* Update CHANGELOG.

Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
This commit is contained in:
Toralf Wittner
2020-08-12 16:04:54 +02:00
committed by GitHub
parent b595972961
commit 30de0b4d64
8 changed files with 557 additions and 16 deletions

View File

@ -281,6 +281,44 @@ pub enum NetworkBehaviourAction<TInEvent, TOutEvent> {
},
}
impl<TInEvent, TOutEvent> NetworkBehaviourAction<TInEvent, TOutEvent> {
/// Map the handler event.
pub fn map_in<E>(self, f: impl FnOnce(TInEvent) -> E) -> NetworkBehaviourAction<E, TOutEvent> {
match self {
NetworkBehaviourAction::GenerateEvent(e) =>
NetworkBehaviourAction::GenerateEvent(e),
NetworkBehaviourAction::DialAddress { address } =>
NetworkBehaviourAction::DialAddress { address },
NetworkBehaviourAction::DialPeer { peer_id, condition } =>
NetworkBehaviourAction::DialPeer { peer_id, condition },
NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } =>
NetworkBehaviourAction::NotifyHandler {
peer_id,
handler,
event: f(event)
},
NetworkBehaviourAction::ReportObservedAddr { address } =>
NetworkBehaviourAction::ReportObservedAddr { address }
}
}
/// Map the event the swarm will return.
pub fn map_out<E>(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction<TInEvent, E> {
match self {
NetworkBehaviourAction::GenerateEvent(e) =>
NetworkBehaviourAction::GenerateEvent(f(e)),
NetworkBehaviourAction::DialAddress { address } =>
NetworkBehaviourAction::DialAddress { address },
NetworkBehaviourAction::DialPeer { peer_id, condition } =>
NetworkBehaviourAction::DialPeer { peer_id, condition },
NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } =>
NetworkBehaviourAction::NotifyHandler { peer_id, handler, event },
NetworkBehaviourAction::ReportObservedAddr { address } =>
NetworkBehaviourAction::ReportObservedAddr { address }
}
}
}
/// The options w.r.t. which connection handlers to notify of an event.
#[derive(Debug, Clone)]
pub enum NotifyHandler {