Add a send_request function to NetworkService (#8008)

* Add a `send_request` to `NetworkService`.

This function delivers responses via a provided sender and also allows
for sending requests to currently not connected peers.

* Document caveats of send_request better.

* Fix compilation in certain cases.

* Update docs + introduce IfDisconnected enum

for more readable function calls.

* Doc fix.

* Rename send_request to detached_request.

* Whitespace fix - arrrgh

* Update client/network/src/service.rs

spaces/tabs

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update client/network/src/request_responses.rs

Documentation fix

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

* Update client/network/src/service.rs

Typo.

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

* Update client/network/src/service.rs

Better docs.

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

* Update client/network/src/service.rs

Typo.

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

* Update client/network/src/service.rs

Doc improvements.

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

* Remove error in logs on dialing a peer.

This is now valid behaviour.

* Rename detached_request to start_request.

As suggested by @romanb.

* Fix merged master.

* Fix too long lines.

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
This commit is contained in:
Robert Klotzner
2021-02-02 20:52:12 +01:00
committed by GitHub
parent 73386a4215
commit 3628998d3c
3 changed files with 85 additions and 23 deletions
@@ -196,6 +196,25 @@ impl From<(Cow<'static, str>, RequestId)> for ProtocolRequestId {
}
}
/// When sending a request, what to do on a disconnected recipient.
pub enum IfDisconnected {
/// Try to connect to the peer.
TryConnect,
/// Just fail if the destination is not yet connected.
ImmediateError,
}
/// Convenience functions for `IfDisconnected`.
impl IfDisconnected {
/// Shall we connect to a disconnected peer?
pub fn should_connect(self) -> bool {
match self {
Self::TryConnect => true,
Self::ImmediateError => false,
}
}
}
/// Implementation of `NetworkBehaviour` that provides support for request-response protocols.
pub struct RequestResponsesBehaviour {
/// The multiple sub-protocols, by name.
@@ -269,17 +288,19 @@ impl RequestResponsesBehaviour {
/// Initiates sending a request.
///
/// An error is returned if we are not connected to the target peer or if the protocol doesn't
/// match one that has been registered.
/// If there is no established connection to the target peer, the behavior is determined by the choice of `connect`.
///
/// An error is returned if the protocol doesn't match one that has been registered.
pub fn send_request(
&mut self,
target: &PeerId,
protocol_name: &str,
request: Vec<u8>,
pending_response: oneshot::Sender<Result<Vec<u8>, RequestFailure>>,
connect: IfDisconnected,
) {
if let Some((protocol, _)) = self.protocols.get_mut(protocol_name) {
if protocol.is_connected(target) {
if protocol.is_connected(target) || connect.should_connect() {
let request_id = protocol.send_request(target, request);
let prev_req_id = self.pending_requests.insert(
(protocol_name.to_string().into(), request_id).into(),
@@ -489,7 +510,6 @@ impl NetworkBehaviour for RequestResponsesBehaviour {
return Poll::Ready(NetworkBehaviourAction::DialAddress { address })
}
NetworkBehaviourAction::DialPeer { peer_id, condition } => {
log::error!("The request-response isn't supposed to start dialing peers");
return Poll::Ready(NetworkBehaviourAction::DialPeer {
peer_id,
condition,
@@ -949,6 +969,7 @@ mod tests {
protocol_name,
b"this is a request".to_vec(),
sender,
IfDisconnected::ImmediateError,
);
assert!(response_receiver.is_none());
response_receiver = Some(receiver);
@@ -1037,6 +1058,7 @@ mod tests {
protocol_name,
b"this is a request".to_vec(),
sender,
IfDisconnected::ImmediateError,
);
assert!(response_receiver.is_none());
response_receiver = Some(receiver);
@@ -1179,12 +1201,14 @@ mod tests {
protocol_name_1,
b"this is a request".to_vec(),
sender_1,
IfDisconnected::ImmediateError,
);
swarm_1.send_request(
&peer_id,
protocol_name_2,
b"this is a request".to_vec(),
sender_2,
IfDisconnected::ImmediateError,
);
assert!(response_receivers.is_none());
response_receivers = Some((receiver_1, receiver_2));