mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-23 23:01:33 +00:00
*: 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:
@ -29,7 +29,8 @@ use libp2p_core::connection::{ConnectedPoint, ConnectionId, ListenerId};
|
||||
use libp2p_core::multiaddr::Multiaddr;
|
||||
use libp2p_core::PeerId;
|
||||
use libp2p_swarm::{
|
||||
DialPeerCondition, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
|
||||
DialError, DialPeerCondition, IntoProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction,
|
||||
NotifyHandler, PollParameters,
|
||||
};
|
||||
use std::collections::{hash_map::Entry, HashMap, HashSet, VecDeque};
|
||||
use std::task::{Context, Poll};
|
||||
@ -45,7 +46,7 @@ pub struct Relay {
|
||||
/// [`Self::listeners`] or [`Self::listener_any_relay`].
|
||||
outbox_to_listeners: VecDeque<(PeerId, BehaviourToListenerMsg)>,
|
||||
/// Events that need to be yielded to the outside when polling.
|
||||
outbox_to_swarm: VecDeque<NetworkBehaviourAction<RelayHandlerIn, ()>>,
|
||||
outbox_to_swarm: VecDeque<NetworkBehaviourAction<(), RelayHandlerProto>>,
|
||||
|
||||
/// List of peers the network is connected to.
|
||||
connected_peers: HashMap<PeerId, HashSet<ConnectionId>>,
|
||||
@ -301,7 +302,20 @@ impl NetworkBehaviour for Relay {
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_dial_failure(&mut self, peer_id: &PeerId) {
|
||||
fn inject_dial_failure(
|
||||
&mut self,
|
||||
peer_id: &PeerId,
|
||||
_: Self::ProtocolsHandler,
|
||||
error: DialError,
|
||||
) {
|
||||
if let DialError::DialPeerConditionFalse(
|
||||
DialPeerCondition::Disconnected | DialPeerCondition::NotDialing,
|
||||
) = error
|
||||
{
|
||||
// Return early. The dial, that this dial was canceled for, might still succeed.
|
||||
return;
|
||||
}
|
||||
|
||||
if let Entry::Occupied(o) = self.listeners.entry(*peer_id) {
|
||||
if matches!(o.get(), RelayListener::Connecting { .. }) {
|
||||
// By removing the entry, the channel to the listener is dropped and thus the
|
||||
@ -340,6 +354,7 @@ impl NetworkBehaviour for Relay {
|
||||
peer: &PeerId,
|
||||
connection: &ConnectionId,
|
||||
_: &ConnectedPoint,
|
||||
_: <Self::ProtocolsHandler as IntoProtocolsHandler>::Handler,
|
||||
) {
|
||||
// Remove connection from the set of connections for the given peer. In case the set is
|
||||
// empty it will be removed in `inject_disconnected`.
|
||||
@ -472,10 +487,12 @@ impl NetworkBehaviour for Relay {
|
||||
src_connection_id: connection,
|
||||
},
|
||||
);
|
||||
let handler = self.new_handler();
|
||||
self.outbox_to_swarm
|
||||
.push_back(NetworkBehaviourAction::DialPeer {
|
||||
peer_id: dest_id,
|
||||
condition: DialPeerCondition::NotDialing,
|
||||
handler,
|
||||
});
|
||||
} else {
|
||||
self.outbox_to_swarm
|
||||
@ -562,7 +579,7 @@ impl NetworkBehaviour for Relay {
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
poll_parameters: &mut impl PollParameters,
|
||||
) -> Poll<NetworkBehaviourAction<RelayHandlerIn, Self::OutEvent>> {
|
||||
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ProtocolsHandler>> {
|
||||
if !self.outbox_to_listeners.is_empty() {
|
||||
let relay_peer_id = self.outbox_to_listeners[0].0;
|
||||
|
||||
@ -668,6 +685,7 @@ impl NetworkBehaviour for Relay {
|
||||
return Poll::Ready(NetworkBehaviourAction::DialPeer {
|
||||
peer_id: relay_peer_id,
|
||||
condition: DialPeerCondition::Disconnected,
|
||||
handler: self.new_handler(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -734,6 +752,7 @@ impl NetworkBehaviour for Relay {
|
||||
return Poll::Ready(NetworkBehaviourAction::DialPeer {
|
||||
peer_id: relay_peer_id,
|
||||
condition: DialPeerCondition::Disconnected,
|
||||
handler: self.new_handler(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user