Treat connection limit errors as pending connection errors. (#1546)

* Treat connection limit errors as pending connection errors.

* Remove handler from network event.

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
This commit is contained in:
Roman Borschel 2020-04-09 16:22:49 +02:00 committed by GitHub
parent 803eb10dcd
commit d2eebf2619
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 32 deletions

View File

@ -29,10 +29,6 @@ pub enum ConnectionError<THandlerErr> {
// TODO: Eventually this should also be a custom error? // TODO: Eventually this should also be a custom error?
IO(io::Error), IO(io::Error),
/// The connection was dropped because the connection limit
/// for a peer has been reached.
ConnectionLimit(ConnectionLimit),
/// The connection handler produced an error. /// The connection handler produced an error.
Handler(THandlerErr), Handler(THandlerErr),
} }
@ -48,8 +44,6 @@ where
write!(f, "Connection error: I/O error: {}", err), write!(f, "Connection error: I/O error: {}", err),
ConnectionError::Handler(err) => ConnectionError::Handler(err) =>
write!(f, "Connection error: Handler error: {}", err), write!(f, "Connection error: Handler error: {}", err),
ConnectionError::ConnectionLimit(l) =>
write!(f, "Connection error: Connection limit: {}.", l)
} }
} }
} }
@ -63,7 +57,6 @@ where
match self { match self {
ConnectionError::IO(err) => Some(err), ConnectionError::IO(err) => Some(err),
ConnectionError::Handler(err) => Some(err), ConnectionError::Handler(err) => Some(err),
ConnectionError::ConnectionLimit(..) => None,
} }
} }
} }
@ -78,6 +71,10 @@ pub enum PendingConnectionError<TTransErr> {
/// match the one that was expected or is otherwise invalid. /// match the one that was expected or is otherwise invalid.
InvalidPeerId, InvalidPeerId,
/// The connection was dropped because the connection limit
/// for a peer has been reached.
ConnectionLimit(ConnectionLimit),
/// An I/O error occurred on the connection. /// An I/O error occurred on the connection.
// TODO: Eventually this should also be a custom error? // TODO: Eventually this should also be a custom error?
IO(io::Error), IO(io::Error),
@ -96,6 +93,8 @@ where
write!(f, "Pending connection: Transport error: {}", err), write!(f, "Pending connection: Transport error: {}", err),
PendingConnectionError::InvalidPeerId => PendingConnectionError::InvalidPeerId =>
write!(f, "Pending connection: Invalid peer ID."), write!(f, "Pending connection: Invalid peer ID."),
PendingConnectionError::ConnectionLimit(l) =>
write!(f, "Connection error: Connection limit: {}.", l),
} }
} }
} }
@ -110,6 +109,7 @@ where
PendingConnectionError::IO(err) => Some(err), PendingConnectionError::IO(err) => Some(err),
PendingConnectionError::Transport(err) => Some(err), PendingConnectionError::Transport(err) => Some(err),
PendingConnectionError::InvalidPeerId => None, PendingConnectionError::InvalidPeerId => None,
PendingConnectionError::ConnectionLimit(..) => None,
} }
} }
} }

View File

@ -112,7 +112,7 @@ pub enum PoolEvent<'a, TInEvent, TOutEvent, THandler, TTransErr, THandlerErr, TC
error: PendingConnectionError<TTransErr>, error: PendingConnectionError<TTransErr>,
/// The handler that was supposed to handle the connection, /// The handler that was supposed to handle the connection,
/// if the connection failed before the handler was consumed. /// if the connection failed before the handler was consumed.
handler: THandler, handler: Option<THandler>,
/// The (expected) peer of the failed connection. /// The (expected) peer of the failed connection.
peer: Option<TPeerId>, peer: Option<TPeerId>,
/// A reference to the pool that managed the connection. /// A reference to the pool that managed the connection.
@ -558,7 +558,7 @@ where
id, id,
endpoint, endpoint,
error, error,
handler, handler: Some(handler),
peer, peer,
pool: self pool: self
}) })
@ -588,13 +588,13 @@ where
.map_or(0, |conns| conns.len()); .map_or(0, |conns| conns.len());
if let Err(e) = self.limits.check_established(current) { if let Err(e) = self.limits.check_established(current) {
let connected = entry.close(); let connected = entry.close();
let num_established = u32::try_from(e.current).unwrap(); return Poll::Ready(PoolEvent::PendingConnectionError {
return Poll::Ready(PoolEvent::ConnectionError {
id, id,
connected, endpoint: connected.endpoint,
error: ConnectionError::ConnectionLimit(e), error: PendingConnectionError::ConnectionLimit(e),
num_established, handler: None,
pool: self, peer,
pool: self
}) })
} }
// Peer ID checks must already have happened. See `add_pending`. // Peer ID checks must already have happened. See `add_pending`.

View File

@ -512,7 +512,7 @@ fn on_connection_failed<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TP
id: ConnectionId, id: ConnectionId,
endpoint: ConnectedPoint, endpoint: ConnectedPoint,
error: PendingConnectionError<TTrans::Error>, error: PendingConnectionError<TTrans::Error>,
handler: THandler, handler: Option<THandler>,
) -> (Option<DialingOpts<TPeerId, THandler>>, NetworkEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>) ) -> (Option<DialingOpts<TPeerId, THandler>>, NetworkEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>)
where where
TTrans: Transport, TTrans: Transport,
@ -533,22 +533,29 @@ where
let num_remain = u32::try_from(attempt.next.len()).unwrap(); let num_remain = u32::try_from(attempt.next.len()).unwrap();
let failed_addr = attempt.current.clone(); let failed_addr = attempt.current.clone();
let opts = let (opts, attempts_remaining) =
if num_remain > 0 { if num_remain > 0 {
let next_attempt = attempt.next.remove(0); if let Some(handler) = handler {
let opts = DialingOpts { let next_attempt = attempt.next.remove(0);
peer: peer_id.clone(), let opts = DialingOpts {
handler, peer: peer_id.clone(),
address: next_attempt, handler,
remaining: attempt.next address: next_attempt,
}; remaining: attempt.next
Some(opts) };
(Some(opts), num_remain)
} else {
// The error is "fatal" for the dialing attempt, since
// the handler was already consumed. All potential
// remaining connection attempts are thus void.
(None, 0)
}
} else { } else {
None (None, 0)
}; };
(opts, NetworkEvent::DialError { (opts, NetworkEvent::DialError {
attempts_remaining: num_remain, attempts_remaining,
peer_id, peer_id,
multiaddr: failed_addr, multiaddr: failed_addr,
error, error,
@ -560,7 +567,6 @@ where
(None, NetworkEvent::UnknownPeerDialError { (None, NetworkEvent::UnknownPeerDialError {
multiaddr: address, multiaddr: address,
error, error,
handler,
}), }),
ConnectedPoint::Listener { local_addr, send_back_addr } => ConnectedPoint::Listener { local_addr, send_back_addr } =>
(None, NetworkEvent::IncomingConnectionError { (None, NetworkEvent::IncomingConnectionError {

View File

@ -146,10 +146,6 @@ where
/// The error that happened. /// The error that happened.
error: PendingConnectionError<TTrans::Error>, error: PendingConnectionError<TTrans::Error>,
/// The handler that was passed to `dial()`, if the
/// connection failed before the handler was consumed.
handler: THandler,
}, },
/// An established connection produced an event. /// An established connection produced an event.