*: Dial with handler and return handler on error and closed (#2191)

Require `NetworkBehaviourAction::{DialPeer,DialAddress}` to contain a
`ProtocolsHandler`. This allows a behaviour to attach custom state to its
handler. The behaviour would no longer need to track this state separately
during connection establishment, thus reducing state required in a behaviour.
E.g. in the case of `libp2p-kad` the behaviour can include a `GetRecord` request
in its handler, or e.g. in the case of `libp2p-request-response` the behaviour
can include the first request in the handler.

Return `ProtocolsHandler` on connection error and close. This allows a behaviour
to extract its custom state previously included in the handler on connection
failure and connection closing. E.g. in the case of `libp2p-kad` the behaviour
could extract the attached `GetRecord` from the handler of the failed connection
and then start another connection attempt with a new handler with the same
`GetRecord` or bubble up an error to the user.

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
Max Inden
2021-08-31 17:00:51 +02:00
committed by GitHub
parent b55ee69645
commit c161acfb50
38 changed files with 1111 additions and 477 deletions

View File

@ -19,7 +19,7 @@
// DEALINGS IN THE SOFTWARE.
use crate::{
IntoProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
DialError, IntoProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
ProtocolsHandler,
};
use libp2p_core::{
@ -45,7 +45,7 @@ where
/// The next action to return from `poll`.
///
/// An action is only returned once.
pub next_action: Option<NetworkBehaviourAction<THandler::InEvent, TOutEvent>>,
pub next_action: Option<NetworkBehaviourAction<TOutEvent, THandler>>,
}
impl<THandler, TOutEvent> MockBehaviour<THandler, TOutEvent>
@ -84,7 +84,7 @@ where
&mut self,
_: &mut Context,
_: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<THandler::InEvent, Self::OutEvent>> {
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ProtocolsHandler>> {
self.next_action.take().map_or(Poll::Pending, Poll::Ready)
}
}
@ -202,10 +202,16 @@ where
self.inner.inject_disconnected(peer);
}
fn inject_connection_closed(&mut self, p: &PeerId, c: &ConnectionId, e: &ConnectedPoint) {
fn inject_connection_closed(
&mut self,
p: &PeerId,
c: &ConnectionId,
e: &ConnectedPoint,
handler: <Self::ProtocolsHandler as IntoProtocolsHandler>::Handler,
) {
self.inject_connection_closed
.push((p.clone(), c.clone(), e.clone()));
self.inner.inject_connection_closed(p, c, e);
self.inner.inject_connection_closed(p, c, e, handler);
}
fn inject_event(
@ -228,9 +234,14 @@ where
self.inner.inject_addr_reach_failure(p, a, e);
}
fn inject_dial_failure(&mut self, p: &PeerId) {
fn inject_dial_failure(
&mut self,
p: &PeerId,
handler: Self::ProtocolsHandler,
error: DialError,
) {
self.inject_dial_failure.push(p.clone());
self.inner.inject_dial_failure(p);
self.inner.inject_dial_failure(p, handler, error);
}
fn inject_new_listener(&mut self, id: ListenerId) {
@ -268,12 +279,11 @@ where
self.inner.inject_listener_closed(l, r);
}
fn poll(&mut self, cx: &mut Context, args: &mut impl PollParameters) ->
Poll<NetworkBehaviourAction<
<<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::InEvent,
Self::OutEvent
>>
{
fn poll(
&mut self,
cx: &mut Context,
args: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ProtocolsHandler>> {
self.poll += 1;
self.inner.poll(cx, args)
}