Split address reach error and node reach error (#1013)

* Split address reach error and node reach error

* Small comments about order of operatoins

* Minor doc change
This commit is contained in:
Pierre Krieger
2019-03-20 20:28:55 +01:00
committed by GitHub
parent 3f05de6d7c
commit 34db72a080
3 changed files with 57 additions and 10 deletions

View File

@ -182,7 +182,9 @@ where TBehaviour: NetworkBehaviour,
match me.raw_swarm.peer(peer_id.clone()) { match me.raw_swarm.peer(peer_id.clone()) {
raw_swarm::Peer::NotConnected(peer) => { raw_swarm::Peer::NotConnected(peer) => {
let handler = me.behaviour.new_handler().into_node_handler_builder(); let handler = me.behaviour.new_handler().into_node_handler_builder();
let _ = peer.connect_iter(addrs, handler); if peer.connect_iter(addrs, handler).is_err() {
me.behaviour.inject_dial_failure(&peer_id);
}
}, },
raw_swarm::Peer::PendingConnect(mut peer) => { raw_swarm::Peer::PendingConnect(mut peer) => {
peer.append_multiaddr_attempts(addrs) peer.append_multiaddr_attempts(addrs)
@ -272,11 +274,14 @@ where TBehaviour: NetworkBehaviour,
}, },
Async::Ready(RawSwarmEvent::ListenerClosed { .. }) => {}, Async::Ready(RawSwarmEvent::ListenerClosed { .. }) => {},
Async::Ready(RawSwarmEvent::IncomingConnectionError { .. }) => {}, Async::Ready(RawSwarmEvent::IncomingConnectionError { .. }) => {},
Async::Ready(RawSwarmEvent::DialError { peer_id, multiaddr, error, .. }) => { Async::Ready(RawSwarmEvent::DialError { peer_id, multiaddr, error, new_state }) => {
self.behaviour.inject_dial_failure(Some(&peer_id), &multiaddr, &error); self.behaviour.inject_addr_reach_failure(Some(&peer_id), &multiaddr, &error);
if let raw_swarm::PeerState::NotConnected = new_state {
self.behaviour.inject_dial_failure(&peer_id);
}
}, },
Async::Ready(RawSwarmEvent::UnknownPeerDialError { multiaddr, error, .. }) => { Async::Ready(RawSwarmEvent::UnknownPeerDialError { multiaddr, error, .. }) => {
self.behaviour.inject_dial_failure(None, &multiaddr, &error); self.behaviour.inject_addr_reach_failure(None, &multiaddr, &error);
}, },
} }
@ -362,8 +367,16 @@ pub trait NetworkBehaviour {
event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent
); );
/// Indicates to the behaviour that we tried to reach a node, but failed. /// Indicates to the behaviour that we tried to reach an address, but failed.
fn inject_dial_failure(&mut self, _peer_id: Option<&PeerId>, _addr: &Multiaddr, _error: &dyn error::Error) { ///
/// If we were trying to reach a specific node, its ID is passed as parameter. If this is the
/// last address to attempt for the given node, then `inject_dial_failure` is called afterwards.
fn inject_addr_reach_failure(&mut self, _peer_id: Option<&PeerId>, _addr: &Multiaddr, _error: &dyn error::Error) {
}
/// Indicates to the behaviour that we tried to dial all the addresses known for a node, but
/// failed.
fn inject_dial_failure(&mut self, _peer_id: &PeerId) {
} }
/// Polls for things that swarm should do. /// Polls for things that swarm should do.
@ -443,6 +456,9 @@ pub enum NetworkBehaviourAction<TInEvent, TOutEvent> {
}, },
/// Instructs the swarm to try reach the given peer. /// Instructs the swarm to try reach the given peer.
///
/// In the future, a corresponding `inject_dial_failure` or `inject_connected` function call
/// must be performed.
DialPeer { DialPeer {
/// The peer to try reach. /// The peer to try reach.
peer_id: PeerId, peer_id: PeerId,

View File

@ -214,6 +214,20 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
}) })
}; };
// Build the list of statements to put in the body of `inject_addr_reach_failure()`.
let inject_addr_reach_failure_stmts = {
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
if is_ignored(&field) {
return None;
}
Some(match field.ident {
Some(ref i) => quote!{ self.#i.inject_addr_reach_failure(peer_id, addr, error); },
None => quote!{ self.#field_n.inject_addr_reach_failure(peer_id, addr, error); },
})
})
};
// Build the list of statements to put in the body of `inject_dial_failure()`. // Build the list of statements to put in the body of `inject_dial_failure()`.
let inject_dial_failure_stmts = { let inject_dial_failure_stmts = {
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| { data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
@ -222,8 +236,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
} }
Some(match field.ident { Some(match field.ident {
Some(ref i) => quote!{ self.#i.inject_dial_failure(peer_id, addr, error); }, Some(ref i) => quote!{ self.#i.inject_dial_failure(peer_id); },
None => quote!{ self.#field_n.inject_dial_failure(peer_id, addr, error); }, None => quote!{ self.#field_n.inject_dial_failure(peer_id); },
}) })
}) })
}; };
@ -396,7 +410,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
} }
#[inline] #[inline]
fn inject_dial_failure(&mut self, peer_id: Option<&#peer_id>, addr: &#multiaddr, error: &dyn std::error::Error) { fn inject_addr_reach_failure(&mut self, peer_id: Option<&#peer_id>, addr: &#multiaddr, error: &dyn std::error::Error) {
#(#inject_addr_reach_failure_stmts);*
}
#[inline]
fn inject_dial_failure(&mut self, peer_id: &#peer_id) {
#(#inject_dial_failure_stmts);* #(#inject_dial_failure_stmts);*
} }

View File

@ -470,13 +470,25 @@ where
self.connected_peers.insert(id); self.connected_peers.insert(id);
} }
fn inject_dial_failure(&mut self, peer_id: Option<&PeerId>, addr: &Multiaddr, _: &dyn error::Error) { fn inject_addr_reach_failure(&mut self, peer_id: Option<&PeerId>, addr: &Multiaddr, _: &dyn error::Error) {
if let Some(peer_id) = peer_id { if let Some(peer_id) = peer_id {
if let Some(list) = self.kbuckets.entry(peer_id).value() { if let Some(list) = self.kbuckets.entry(peer_id).value() {
// TODO: don't remove the address if the error is that we are already connected // TODO: don't remove the address if the error is that we are already connected
// to this peer // to this peer
list.remove(addr); list.remove(addr);
} }
for query in self.active_queries.values_mut() {
if let Some(addrs) = query.target_mut().untrusted_addresses.get_mut(peer_id) {
addrs.retain(|a| a != addr);
}
}
}
}
fn inject_dial_failure(&mut self, peer_id: &PeerId) {
for query in self.active_queries.values_mut() {
query.inject_rpc_error(peer_id);
} }
} }