mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-18 12:31:22 +00:00
swarm/src: Remove ConnectionHandler (#2519)
The `ConnectionHandler` trait is not exposed to users. The only implementor of `ConnectionHandler` is `NodeHandlerWrapper`. Thus `ConnectionHandler` is a superfluous abstraction. This commit removes `ConnectionHandler`. Next to this large change, this commit removes the `Tmuxer` trait parameter. `Swarm` enforces dynamic dispatching via `StreamMuxerBox` anyways, thus the trait parameter is useless. As a follow up to this commit one could rename `ProtocolsHandler` to `ConnectionHandler` and `NodeHandlerWrapper` to `ConnectionHandlerWrapper` or just `Wrapper`.
This commit is contained in:
@ -31,9 +31,12 @@ use libp2p_core::{
|
||||
use std::{task::Context, task::Poll};
|
||||
|
||||
/// Custom event that can be received by the [`ProtocolsHandler`].
|
||||
type THandlerInEvent<THandler> =
|
||||
pub(crate) type THandlerInEvent<THandler> =
|
||||
<<THandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::InEvent;
|
||||
|
||||
pub(crate) type THandlerOutEvent<THandler> =
|
||||
<<THandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent;
|
||||
|
||||
/// A [`NetworkBehaviour`] defines the behaviour of the local node on the network.
|
||||
///
|
||||
/// In contrast to [`Transport`](libp2p_core::Transport) which defines **how** to send bytes on the
|
||||
|
@ -19,17 +19,19 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
mod error;
|
||||
pub(crate) mod handler;
|
||||
mod listeners;
|
||||
mod substream;
|
||||
|
||||
pub(crate) mod pool;
|
||||
|
||||
use crate::protocols_handler::{
|
||||
NodeHandlerWrapper, NodeHandlerWrapperError, NodeHandlerWrapperEvent,
|
||||
NodeHandlerWrapperOutboundOpenInfo, ProtocolsHandler,
|
||||
};
|
||||
pub use error::{
|
||||
ConnectionError, PendingConnectionError, PendingInboundConnectionError,
|
||||
PendingOutboundConnectionError,
|
||||
};
|
||||
pub use handler::{ConnectionHandler, ConnectionHandlerEvent, IntoConnectionHandler};
|
||||
pub use listeners::{ListenersEvent, ListenersStream};
|
||||
pub use pool::{ConnectionCounters, ConnectionLimits};
|
||||
pub use pool::{EstablishedConnection, PendingConnection};
|
||||
@ -37,7 +39,7 @@ pub use substream::{Close, Substream, SubstreamEndpoint};
|
||||
|
||||
use libp2p_core::connection::ConnectedPoint;
|
||||
use libp2p_core::multiaddr::Multiaddr;
|
||||
use libp2p_core::muxing::StreamMuxer;
|
||||
use libp2p_core::muxing::StreamMuxerBox;
|
||||
use libp2p_core::PeerId;
|
||||
use std::{error::Error, fmt, pin::Pin, task::Context, task::Poll};
|
||||
use substream::{Muxing, SubstreamEvent};
|
||||
@ -54,28 +56,26 @@ pub struct Connected {
|
||||
/// Event generated by a [`Connection`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Event<T> {
|
||||
/// Event generated by the [`ConnectionHandler`].
|
||||
/// Event generated by the [`NodeHandlerWrapper`].
|
||||
Handler(T),
|
||||
/// Address of the remote has changed.
|
||||
AddressChange(Multiaddr),
|
||||
}
|
||||
|
||||
/// A multiplexed connection to a peer with an associated `ConnectionHandler`.
|
||||
pub struct Connection<TMuxer, THandler>
|
||||
/// A multiplexed connection to a peer with an associated [`NodeHandlerWrapper`].
|
||||
pub struct Connection<THandler>
|
||||
where
|
||||
TMuxer: StreamMuxer,
|
||||
THandler: ConnectionHandler<Substream = Substream<TMuxer>>,
|
||||
THandler: ProtocolsHandler,
|
||||
{
|
||||
/// Node that handles the muxing.
|
||||
muxing: substream::Muxing<TMuxer, THandler::OutboundOpenInfo>,
|
||||
muxing: substream::Muxing<StreamMuxerBox, NodeHandlerWrapperOutboundOpenInfo<THandler>>,
|
||||
/// Handler that processes substreams.
|
||||
handler: THandler,
|
||||
handler: NodeHandlerWrapper<THandler>,
|
||||
}
|
||||
|
||||
impl<TMuxer, THandler> fmt::Debug for Connection<TMuxer, THandler>
|
||||
impl<THandler> fmt::Debug for Connection<THandler>
|
||||
where
|
||||
TMuxer: StreamMuxer,
|
||||
THandler: ConnectionHandler<Substream = Substream<TMuxer>> + fmt::Debug,
|
||||
THandler: ProtocolsHandler + fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Connection")
|
||||
@ -85,21 +85,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TMuxer, THandler> Unpin for Connection<TMuxer, THandler>
|
||||
where
|
||||
TMuxer: StreamMuxer,
|
||||
THandler: ConnectionHandler<Substream = Substream<TMuxer>>,
|
||||
{
|
||||
}
|
||||
impl<THandler> Unpin for Connection<THandler> where THandler: ProtocolsHandler {}
|
||||
|
||||
impl<TMuxer, THandler> Connection<TMuxer, THandler>
|
||||
impl<THandler> Connection<THandler>
|
||||
where
|
||||
TMuxer: StreamMuxer,
|
||||
THandler: ConnectionHandler<Substream = Substream<TMuxer>>,
|
||||
THandler: ProtocolsHandler,
|
||||
{
|
||||
/// Builds a new `Connection` from the given substream multiplexer
|
||||
/// and connection handler.
|
||||
pub fn new(muxer: TMuxer, handler: THandler) -> Self {
|
||||
pub fn new(muxer: StreamMuxerBox, handler: NodeHandlerWrapper<THandler>) -> Self {
|
||||
Connection {
|
||||
muxing: Muxing::new(muxer),
|
||||
handler,
|
||||
@ -113,7 +107,7 @@ where
|
||||
|
||||
/// Begins an orderly shutdown of the connection, returning the connection
|
||||
/// handler and a `Future` that resolves when connection shutdown is complete.
|
||||
pub fn close(self) -> (THandler, Close<TMuxer>) {
|
||||
pub fn close(self) -> (NodeHandlerWrapper<THandler>, Close<StreamMuxerBox>) {
|
||||
(self.handler, self.muxing.close().0)
|
||||
}
|
||||
|
||||
@ -122,7 +116,12 @@ where
|
||||
pub fn poll(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<Event<THandler::OutEvent>, ConnectionError<THandler::Error>>> {
|
||||
) -> Poll<
|
||||
Result<
|
||||
Event<THandler::OutEvent>,
|
||||
ConnectionError<NodeHandlerWrapperError<THandler::Error>>,
|
||||
>,
|
||||
> {
|
||||
loop {
|
||||
let mut io_pending = false;
|
||||
|
||||
@ -154,10 +153,10 @@ where
|
||||
return Poll::Pending; // Nothing to do
|
||||
}
|
||||
}
|
||||
Poll::Ready(Ok(ConnectionHandlerEvent::OutboundSubstreamRequest(user_data))) => {
|
||||
Poll::Ready(Ok(NodeHandlerWrapperEvent::OutboundSubstreamRequest(user_data))) => {
|
||||
self.muxing.open_substream(user_data);
|
||||
}
|
||||
Poll::Ready(Ok(ConnectionHandlerEvent::Custom(event))) => {
|
||||
Poll::Ready(Ok(NodeHandlerWrapperEvent::Custom(event))) => {
|
||||
return Poll::Ready(Ok(Event::Handler(event)));
|
||||
}
|
||||
Poll::Ready(Err(err)) => return Poll::Ready(Err(ConnectionError::Handler(err))),
|
||||
|
@ -1,115 +0,0 @@
|
||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use super::{Connected, SubstreamEndpoint};
|
||||
use crate::Multiaddr;
|
||||
use std::{fmt::Debug, task::Context, task::Poll};
|
||||
|
||||
/// The interface of a connection handler.
|
||||
///
|
||||
/// Each handler is responsible for a single connection.
|
||||
pub trait ConnectionHandler {
|
||||
/// The inbound type of events used to notify the handler through the `Network`.
|
||||
///
|
||||
/// See also [`EstablishedConnection::notify_handler`](super::EstablishedConnection::notify_handler)
|
||||
/// and [`ConnectionHandler::inject_event`].
|
||||
type InEvent: Debug + Send + 'static;
|
||||
/// The outbound type of events that the handler emits to the `Network`
|
||||
/// through [`ConnectionHandler::poll`].
|
||||
///
|
||||
/// See also [`PoolEvent::ConnectionEvent`](crate::connection::pool::PoolEvent::ConnectionEvent).
|
||||
type OutEvent: Debug + Send + 'static;
|
||||
/// The type of errors that the handler can produce when polled by the `Network`.
|
||||
type Error: Debug + Send + 'static;
|
||||
/// The type of the substream containing the data.
|
||||
type Substream;
|
||||
/// Information about a substream. Can be sent to the handler through a `SubstreamEndpoint`,
|
||||
/// and will be passed back in `inject_substream` or `inject_outbound_closed`.
|
||||
type OutboundOpenInfo;
|
||||
|
||||
/// Sends a new substream to the handler.
|
||||
///
|
||||
/// The handler is responsible for upgrading the substream to whatever protocol it wants.
|
||||
///
|
||||
/// # Panic
|
||||
///
|
||||
/// Implementations are allowed to panic in the case of dialing if the `user_data` in
|
||||
/// `endpoint` doesn't correspond to what was returned earlier when polling, or is used
|
||||
/// multiple times.
|
||||
fn inject_substream(
|
||||
&mut self,
|
||||
substream: Self::Substream,
|
||||
endpoint: SubstreamEndpoint<Self::OutboundOpenInfo>,
|
||||
);
|
||||
|
||||
/// Notifies the handler of an event.
|
||||
fn inject_event(&mut self, event: Self::InEvent);
|
||||
|
||||
/// Notifies the handler of a change in the address of the remote.
|
||||
fn inject_address_change(&mut self, new_address: &Multiaddr);
|
||||
|
||||
/// Polls the handler for events.
|
||||
///
|
||||
/// Returning an error will close the connection to the remote.
|
||||
fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<ConnectionHandlerEvent<Self::OutboundOpenInfo, Self::OutEvent>, Self::Error>>;
|
||||
}
|
||||
|
||||
/// Prototype for a `ConnectionHandler`.
|
||||
pub trait IntoConnectionHandler {
|
||||
/// The node handler.
|
||||
type Handler: ConnectionHandler;
|
||||
|
||||
/// Builds the node handler.
|
||||
///
|
||||
/// The implementation is given a `Connected` value that holds information about
|
||||
/// the newly established connection for which a handler should be created.
|
||||
fn into_handler(self, connected: &Connected) -> Self::Handler;
|
||||
}
|
||||
|
||||
impl<T> IntoConnectionHandler for T
|
||||
where
|
||||
T: ConnectionHandler,
|
||||
{
|
||||
type Handler = Self;
|
||||
|
||||
fn into_handler(self, _: &Connected) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type THandlerInEvent<THandler> =
|
||||
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent;
|
||||
pub(crate) type THandlerOutEvent<THandler> =
|
||||
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent;
|
||||
pub(crate) type THandlerError<THandler> =
|
||||
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::Error;
|
||||
|
||||
/// Event produced by a handler.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ConnectionHandlerEvent<TOutboundOpenInfo, TCustom> {
|
||||
/// Require a new outbound substream to be opened with the remote.
|
||||
OutboundSubstreamRequest(TOutboundOpenInfo),
|
||||
|
||||
/// Other event.
|
||||
Custom(TCustom),
|
||||
}
|
@ -20,14 +20,14 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
behaviour::{THandlerInEvent, THandlerOutEvent},
|
||||
connection::{
|
||||
handler::{THandlerError, THandlerInEvent, THandlerOutEvent},
|
||||
Connected, ConnectionError, ConnectionHandler, ConnectionLimit, IncomingInfo,
|
||||
IntoConnectionHandler, PendingConnectionError, PendingInboundConnectionError,
|
||||
PendingOutboundConnectionError, Substream,
|
||||
Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError,
|
||||
PendingInboundConnectionError, PendingOutboundConnectionError,
|
||||
},
|
||||
protocols_handler::{NodeHandlerWrapper, NodeHandlerWrapperBuilder, NodeHandlerWrapperError},
|
||||
transport::{Transport, TransportError},
|
||||
ConnectedPoint, Executor, Multiaddr, PeerId,
|
||||
ConnectedPoint, Executor, IntoProtocolsHandler, Multiaddr, PeerId, ProtocolsHandler,
|
||||
};
|
||||
use concurrent_dial::ConcurrentDial;
|
||||
use fnv::FnvHashMap;
|
||||
@ -39,7 +39,7 @@ use futures::{
|
||||
stream::FuturesUnordered,
|
||||
};
|
||||
use libp2p_core::connection::{ConnectionId, Endpoint, PendingPoint};
|
||||
use libp2p_core::muxing::StreamMuxer;
|
||||
use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox};
|
||||
use std::{
|
||||
collections::{hash_map, HashMap},
|
||||
convert::TryFrom as _,
|
||||
@ -55,7 +55,7 @@ mod concurrent_dial;
|
||||
mod task;
|
||||
|
||||
/// A connection `Pool` manages a set of connections for each peer.
|
||||
pub struct Pool<THandler: IntoConnectionHandler, TTrans>
|
||||
pub struct Pool<THandler: IntoProtocolsHandler, TTrans>
|
||||
where
|
||||
TTrans: Transport,
|
||||
{
|
||||
@ -67,7 +67,10 @@ where
|
||||
/// The managed connections of each peer that are currently considered established.
|
||||
established: FnvHashMap<
|
||||
PeerId,
|
||||
FnvHashMap<ConnectionId, EstablishedConnectionInfo<THandlerInEvent<THandler>>>,
|
||||
FnvHashMap<
|
||||
ConnectionId,
|
||||
EstablishedConnectionInfo<<THandler::Handler as ProtocolsHandler>::InEvent>,
|
||||
>,
|
||||
>,
|
||||
|
||||
/// The pending connections that are currently being negotiated.
|
||||
@ -100,10 +103,12 @@ where
|
||||
|
||||
/// Sender distributed to established tasks for reporting events back
|
||||
/// to the pool.
|
||||
established_connection_events_tx: mpsc::Sender<task::EstablishedConnectionEvent<THandler>>,
|
||||
established_connection_events_tx:
|
||||
mpsc::Sender<task::EstablishedConnectionEvent<THandler::Handler>>,
|
||||
|
||||
/// Receiver for events reported from established tasks.
|
||||
established_connection_events_rx: mpsc::Receiver<task::EstablishedConnectionEvent<THandler>>,
|
||||
established_connection_events_rx:
|
||||
mpsc::Receiver<task::EstablishedConnectionEvent<THandler::Handler>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -133,13 +138,13 @@ struct PendingConnectionInfo<THandler> {
|
||||
/// [`PeerId`] of the remote peer.
|
||||
peer_id: Option<PeerId>,
|
||||
/// Handler to handle connection once no longer pending but established.
|
||||
handler: THandler,
|
||||
handler: NodeHandlerWrapperBuilder<THandler>,
|
||||
endpoint: PendingPoint,
|
||||
/// When dropped, notifies the task which then knows to terminate.
|
||||
abort_notifier: Option<oneshot::Sender<Void>>,
|
||||
}
|
||||
|
||||
impl<THandler: IntoConnectionHandler, TTrans: Transport> fmt::Debug for Pool<THandler, TTrans> {
|
||||
impl<THandler: IntoProtocolsHandler, TTrans: Transport> fmt::Debug for Pool<THandler, TTrans> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
f.debug_struct("Pool")
|
||||
.field("counters", &self.counters)
|
||||
@ -148,13 +153,13 @@ impl<THandler: IntoConnectionHandler, TTrans: Transport> fmt::Debug for Pool<THa
|
||||
}
|
||||
|
||||
/// Event that can happen on the `Pool`.
|
||||
pub enum PoolEvent<'a, THandler: IntoConnectionHandler, TTrans>
|
||||
pub enum PoolEvent<'a, THandler: IntoProtocolsHandler, TTrans>
|
||||
where
|
||||
TTrans: Transport,
|
||||
{
|
||||
/// A new connection has been established.
|
||||
ConnectionEstablished {
|
||||
connection: EstablishedConnection<'a, THandlerInEvent<THandler>>,
|
||||
connection: EstablishedConnection<'a, <THandler::Handler as ProtocolsHandler>::InEvent>,
|
||||
/// List of other connections to the same peer.
|
||||
///
|
||||
/// Note: Does not include the connection reported through this event.
|
||||
@ -182,12 +187,16 @@ where
|
||||
connected: Connected,
|
||||
/// The error that occurred, if any. If `None`, the connection
|
||||
/// was closed by the local peer.
|
||||
error: Option<ConnectionError<THandlerError<THandler>>>,
|
||||
error: Option<
|
||||
ConnectionError<
|
||||
NodeHandlerWrapperError<<THandler::Handler as ProtocolsHandler>::Error>,
|
||||
>,
|
||||
>,
|
||||
/// A reference to the pool that used to manage the connection.
|
||||
pool: &'a mut Pool<THandler, TTrans>,
|
||||
/// The remaining established connections to the same peer.
|
||||
remaining_established_connection_ids: Vec<ConnectionId>,
|
||||
handler: THandler::Handler,
|
||||
handler: NodeHandlerWrapper<THandler::Handler>,
|
||||
},
|
||||
|
||||
/// An outbound connection attempt failed.
|
||||
@ -197,7 +206,7 @@ where
|
||||
/// The error that occurred.
|
||||
error: PendingOutboundConnectionError<TTrans::Error>,
|
||||
/// The handler that was supposed to handle the connection.
|
||||
handler: THandler,
|
||||
handler: NodeHandlerWrapperBuilder<THandler>,
|
||||
/// The (expected) peer of the failed connection.
|
||||
peer: Option<PeerId>,
|
||||
},
|
||||
@ -213,7 +222,7 @@ where
|
||||
/// The error that occurred.
|
||||
error: PendingInboundConnectionError<TTrans::Error>,
|
||||
/// The handler that was supposed to handle the connection.
|
||||
handler: THandler,
|
||||
handler: NodeHandlerWrapperBuilder<THandler>,
|
||||
},
|
||||
|
||||
/// A node has produced an event.
|
||||
@ -235,7 +244,7 @@ where
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a, THandler: IntoConnectionHandler, TTrans> fmt::Debug for PoolEvent<'a, THandler, TTrans>
|
||||
impl<'a, THandler: IntoProtocolsHandler, TTrans> fmt::Debug for PoolEvent<'a, THandler, TTrans>
|
||||
where
|
||||
TTrans: Transport,
|
||||
TTrans::Error: fmt::Debug,
|
||||
@ -304,7 +313,7 @@ where
|
||||
|
||||
impl<THandler, TTrans> Pool<THandler, TTrans>
|
||||
where
|
||||
THandler: IntoConnectionHandler,
|
||||
THandler: IntoProtocolsHandler,
|
||||
TTrans: Transport,
|
||||
{
|
||||
/// Creates a new empty `Pool`.
|
||||
@ -457,7 +466,7 @@ where
|
||||
|
||||
impl<THandler, TTrans> Pool<THandler, TTrans>
|
||||
where
|
||||
THandler: IntoConnectionHandler,
|
||||
THandler: IntoProtocolsHandler,
|
||||
TTrans: Transport + 'static,
|
||||
TTrans::Output: Send + 'static,
|
||||
TTrans::Error: Send + 'static,
|
||||
@ -472,10 +481,10 @@ where
|
||||
transport: TTrans,
|
||||
addresses: impl Iterator<Item = Multiaddr> + Send + 'static,
|
||||
peer: Option<PeerId>,
|
||||
handler: THandler,
|
||||
handler: NodeHandlerWrapperBuilder<THandler>,
|
||||
role_override: Endpoint,
|
||||
dial_concurrency_factor_override: Option<NonZeroU8>,
|
||||
) -> Result<ConnectionId, (ConnectionLimit, THandler)>
|
||||
) -> Result<ConnectionId, (ConnectionLimit, NodeHandlerWrapperBuilder<THandler>)>
|
||||
where
|
||||
TTrans: Clone + Send,
|
||||
TTrans::Dial: Send + 'static,
|
||||
@ -529,9 +538,9 @@ where
|
||||
pub fn add_incoming<TFut>(
|
||||
&mut self,
|
||||
future: TFut,
|
||||
handler: THandler,
|
||||
handler: NodeHandlerWrapperBuilder<THandler>,
|
||||
info: IncomingInfo<'_>,
|
||||
) -> Result<ConnectionId, (ConnectionLimit, THandler)>
|
||||
) -> Result<ConnectionId, (ConnectionLimit, NodeHandlerWrapperBuilder<THandler>)>
|
||||
where
|
||||
TFut: Future<Output = Result<TTrans::Output, TTrans::Error>> + Send + 'static,
|
||||
{
|
||||
@ -571,18 +580,12 @@ where
|
||||
///
|
||||
/// > **Note**: We use a regular `poll` method instead of implementing `Stream`,
|
||||
/// > because we want the `Pool` to stay borrowed if necessary.
|
||||
pub fn poll<'a, TMuxer>(
|
||||
&'a mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<PoolEvent<'a, THandler, TTrans>>
|
||||
pub fn poll<'a>(&'a mut self, cx: &mut Context<'_>) -> Poll<PoolEvent<'a, THandler, TTrans>>
|
||||
where
|
||||
TTrans: Transport<Output = (PeerId, TMuxer)>,
|
||||
TMuxer: StreamMuxer + Send + Sync + 'static,
|
||||
TMuxer::Error: std::fmt::Debug,
|
||||
TMuxer::OutboundSubstream: Send,
|
||||
THandler: IntoConnectionHandler + 'static,
|
||||
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send,
|
||||
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send,
|
||||
TTrans: Transport<Output = (PeerId, StreamMuxerBox)>,
|
||||
THandler: IntoProtocolsHandler + 'static,
|
||||
THandler::Handler: ProtocolsHandler + Send,
|
||||
<THandler::Handler as ProtocolsHandler>::OutboundOpenInfo: Send,
|
||||
{
|
||||
// Poll for events of established connections.
|
||||
//
|
||||
@ -896,17 +899,17 @@ where
|
||||
}
|
||||
|
||||
/// A connection in a [`Pool`].
|
||||
pub enum PoolConnection<'a, THandler: IntoConnectionHandler> {
|
||||
pub enum PoolConnection<'a, THandler: IntoProtocolsHandler> {
|
||||
Pending(PendingConnection<'a, THandler>),
|
||||
Established(EstablishedConnection<'a, THandlerInEvent<THandler>>),
|
||||
}
|
||||
|
||||
/// A pending connection in a pool.
|
||||
pub struct PendingConnection<'a, THandler: IntoConnectionHandler> {
|
||||
pub struct PendingConnection<'a, THandler: IntoProtocolsHandler> {
|
||||
entry: hash_map::OccupiedEntry<'a, ConnectionId, PendingConnectionInfo<THandler>>,
|
||||
}
|
||||
|
||||
impl<THandler: IntoConnectionHandler> PendingConnection<'_, THandler> {
|
||||
impl<THandler: IntoProtocolsHandler> PendingConnection<'_, THandler> {
|
||||
/// Aborts the connection attempt, closing the connection.
|
||||
pub fn abort(mut self) {
|
||||
if let Some(notifier) = self.entry.get_mut().abort_notifier.take() {
|
||||
@ -1259,7 +1262,7 @@ impl PoolConfig {
|
||||
/// delivery to the connection handler.
|
||||
///
|
||||
/// When the buffer for a particular connection is full, `notify_handler` will no
|
||||
/// longer be able to deliver events to the associated `ConnectionHandler`,
|
||||
/// longer be able to deliver events to the associated [`Connection`](super::Connection),
|
||||
/// thus exerting back-pressure on the connection and peer API.
|
||||
pub fn with_notify_handler_buffer_size(mut self, n: NonZeroUsize) -> Self {
|
||||
self.task_command_buffer_size = n.get() - 1;
|
||||
|
@ -24,13 +24,11 @@
|
||||
use super::concurrent_dial::ConcurrentDial;
|
||||
use crate::{
|
||||
connection::{
|
||||
self,
|
||||
handler::{THandlerError, THandlerInEvent, THandlerOutEvent},
|
||||
ConnectionError, ConnectionHandler, IntoConnectionHandler, PendingInboundConnectionError,
|
||||
PendingOutboundConnectionError, Substream,
|
||||
self, ConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError,
|
||||
},
|
||||
protocols_handler::{NodeHandlerWrapper, NodeHandlerWrapperError},
|
||||
transport::{Transport, TransportError},
|
||||
Multiaddr, PeerId,
|
||||
Multiaddr, PeerId, ProtocolsHandler,
|
||||
};
|
||||
use futures::{
|
||||
channel::{mpsc, oneshot},
|
||||
@ -38,7 +36,6 @@ use futures::{
|
||||
SinkExt, StreamExt,
|
||||
};
|
||||
use libp2p_core::connection::ConnectionId;
|
||||
use libp2p_core::muxing::StreamMuxer;
|
||||
use std::pin::Pin;
|
||||
use void::Void;
|
||||
|
||||
@ -76,7 +73,7 @@ where
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EstablishedConnectionEvent<THandler: IntoConnectionHandler> {
|
||||
pub enum EstablishedConnectionEvent<THandler: ProtocolsHandler> {
|
||||
/// A node we are connected to has changed its address.
|
||||
AddressChange {
|
||||
id: ConnectionId,
|
||||
@ -87,7 +84,7 @@ pub enum EstablishedConnectionEvent<THandler: IntoConnectionHandler> {
|
||||
Notify {
|
||||
id: ConnectionId,
|
||||
peer_id: PeerId,
|
||||
event: THandlerOutEvent<THandler>,
|
||||
event: THandler::OutEvent,
|
||||
},
|
||||
/// A connection closed, possibly due to an error.
|
||||
///
|
||||
@ -96,8 +93,8 @@ pub enum EstablishedConnectionEvent<THandler: IntoConnectionHandler> {
|
||||
Closed {
|
||||
id: ConnectionId,
|
||||
peer_id: PeerId,
|
||||
error: Option<ConnectionError<THandlerError<THandler>>>,
|
||||
handler: THandler::Handler,
|
||||
error: Option<ConnectionError<NodeHandlerWrapperError<THandler::Error>>>,
|
||||
handler: NodeHandlerWrapper<THandler>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -180,16 +177,14 @@ pub async fn new_for_pending_incoming_connection<TFut, TTrans>(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn new_for_established_connection<TMuxer, THandler>(
|
||||
pub async fn new_for_established_connection<THandler>(
|
||||
connection_id: ConnectionId,
|
||||
peer_id: PeerId,
|
||||
mut connection: crate::connection::Connection<TMuxer, THandler::Handler>,
|
||||
mut command_receiver: mpsc::Receiver<Command<THandlerInEvent<THandler>>>,
|
||||
mut connection: crate::connection::Connection<THandler>,
|
||||
mut command_receiver: mpsc::Receiver<Command<THandler::InEvent>>,
|
||||
mut events: mpsc::Sender<EstablishedConnectionEvent<THandler>>,
|
||||
) where
|
||||
TMuxer: StreamMuxer,
|
||||
THandler: IntoConnectionHandler,
|
||||
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>>,
|
||||
THandler: ProtocolsHandler,
|
||||
{
|
||||
loop {
|
||||
match futures::future::select(
|
||||
|
@ -79,8 +79,8 @@ use crate::connection::IncomingInfo;
|
||||
use crate::connection::{pool::PoolEvent, ListenersEvent, ListenersStream};
|
||||
use connection::pool::{ConnectionCounters, ConnectionLimits, Pool, PoolConfig};
|
||||
use connection::{
|
||||
ConnectionError, ConnectionHandler, ConnectionLimit, EstablishedConnection,
|
||||
IntoConnectionHandler, PendingOutboundConnectionError, Substream,
|
||||
ConnectionError, ConnectionLimit, EstablishedConnection, PendingOutboundConnectionError,
|
||||
Substream,
|
||||
};
|
||||
use dial_opts::{DialOpts, PeerCondition};
|
||||
use either::Either;
|
||||
@ -95,7 +95,7 @@ use libp2p_core::{
|
||||
upgrade::ProtocolName,
|
||||
Executor, Multiaddr, Negotiated, PeerId, Transport,
|
||||
};
|
||||
use protocols_handler::{NodeHandlerWrapperBuilder, NodeHandlerWrapperError};
|
||||
use protocols_handler::NodeHandlerWrapperError;
|
||||
use registry::{AddressIntoIter, Addresses};
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::HashSet;
|
||||
@ -264,10 +264,7 @@ where
|
||||
listeners: ListenersStream<transport::Boxed<(PeerId, StreamMuxerBox)>>,
|
||||
|
||||
/// The nodes currently active.
|
||||
pool: Pool<
|
||||
NodeHandlerWrapperBuilder<THandler<TBehaviour>>,
|
||||
transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||
>,
|
||||
pool: Pool<THandler<TBehaviour>, transport::Boxed<(PeerId, StreamMuxerBox)>>,
|
||||
|
||||
/// The local peer ID.
|
||||
local_peer_id: PeerId,
|
||||
@ -1147,8 +1144,8 @@ where
|
||||
TTrans: Transport,
|
||||
TTrans::Error: Send + 'static,
|
||||
TBehaviour: NetworkBehaviour,
|
||||
THandler: IntoConnectionHandler,
|
||||
THandler::Handler: ConnectionHandler<
|
||||
THandler: IntoProtocolsHandler,
|
||||
THandler::Handler: ProtocolsHandler<
|
||||
InEvent = THandlerInEvent<TBehaviour>,
|
||||
OutEvent = THandlerOutEvent<TBehaviour>,
|
||||
>,
|
||||
|
@ -55,7 +55,10 @@ use std::{cmp::Ordering, error, fmt, task::Context, task::Poll, time::Duration};
|
||||
pub use dummy::DummyProtocolsHandler;
|
||||
pub use map_in::MapInEvent;
|
||||
pub use map_out::MapOutEvent;
|
||||
pub use node_handler::{NodeHandlerWrapper, NodeHandlerWrapperBuilder, NodeHandlerWrapperError};
|
||||
pub use node_handler::{
|
||||
NodeHandlerWrapper, NodeHandlerWrapperBuilder, NodeHandlerWrapperError,
|
||||
NodeHandlerWrapperEvent, NodeHandlerWrapperOutboundOpenInfo,
|
||||
};
|
||||
pub use one_shot::{OneShotHandler, OneShotHandlerConfig};
|
||||
pub use select::{IntoProtocolsHandlerSelect, ProtocolsHandlerSelect};
|
||||
|
||||
|
@ -18,10 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::connection::{
|
||||
Connected, ConnectionHandler, ConnectionHandlerEvent, IntoConnectionHandler, Substream,
|
||||
SubstreamEndpoint,
|
||||
};
|
||||
use crate::connection::{Connected, Substream, SubstreamEndpoint};
|
||||
use crate::protocols_handler::{
|
||||
IntoProtocolsHandler, KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
@ -72,15 +69,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TIntoProtoHandler, TProtoHandler> IntoConnectionHandler
|
||||
for NodeHandlerWrapperBuilder<TIntoProtoHandler>
|
||||
impl<TIntoProtoHandler, TProtoHandler> NodeHandlerWrapperBuilder<TIntoProtoHandler>
|
||||
where
|
||||
TIntoProtoHandler: IntoProtocolsHandler<Handler = TProtoHandler>,
|
||||
TProtoHandler: ProtocolsHandler,
|
||||
{
|
||||
type Handler = NodeHandlerWrapper<TIntoProtoHandler::Handler>;
|
||||
|
||||
fn into_handler(self, connected: &Connected) -> Self::Handler {
|
||||
pub fn into_handler(self, connected: &Connected) -> NodeHandlerWrapper<TProtoHandler> {
|
||||
NodeHandlerWrapper {
|
||||
handler: self
|
||||
.handler
|
||||
@ -95,8 +89,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// A `ConnectionHandler` for an underlying `ProtocolsHandler`.
|
||||
/// Wraps around an implementation of `ProtocolsHandler`, and implements `NodeHandler`.
|
||||
/// A wrapper for an underlying [`ProtocolsHandler`].
|
||||
///
|
||||
/// It extends [`ProtocolsHandler`] with:
|
||||
/// - Enforced substream upgrade timeouts
|
||||
/// - Driving substream upgrades
|
||||
/// - Handling connection timeout
|
||||
// TODO: add a caching system for protocols that are supported or not
|
||||
pub struct NodeHandlerWrapper<TProtoHandler>
|
||||
where
|
||||
@ -135,6 +133,21 @@ where
|
||||
substream_upgrade_protocol_override: Option<upgrade::Version>,
|
||||
}
|
||||
|
||||
impl<TProtoHandler: ProtocolsHandler> std::fmt::Debug for NodeHandlerWrapper<TProtoHandler> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("NodeHandlerWrapper")
|
||||
.field("negotiating_in", &self.negotiating_in)
|
||||
.field("negotiating_out", &self.negotiating_out)
|
||||
.field("unique_dial_upgrade_id", &self.unique_dial_upgrade_id)
|
||||
.field("shutdown", &self.shutdown)
|
||||
.field(
|
||||
"substream_upgrade_protocol_override",
|
||||
&self.substream_upgrade_protocol_override,
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<TProtoHandler: ProtocolsHandler> NodeHandlerWrapper<TProtoHandler> {
|
||||
pub(crate) fn into_protocols_handler(self) -> TProtoHandler {
|
||||
self.handler
|
||||
@ -199,6 +212,7 @@ where
|
||||
/// A planned shutdown is always postponed for as long as there are ingoing
|
||||
/// or outgoing substreams being negotiated, i.e. it is a graceful, "idle"
|
||||
/// shutdown.
|
||||
#[derive(Debug)]
|
||||
enum Shutdown {
|
||||
/// No shutdown is planned.
|
||||
None,
|
||||
@ -249,22 +263,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TProtoHandler> ConnectionHandler for NodeHandlerWrapper<TProtoHandler>
|
||||
pub type NodeHandlerWrapperOutboundOpenInfo<TProtoHandler> = (
|
||||
u64,
|
||||
<TProtoHandler as ProtocolsHandler>::OutboundOpenInfo,
|
||||
Duration,
|
||||
);
|
||||
|
||||
impl<TProtoHandler> NodeHandlerWrapper<TProtoHandler>
|
||||
where
|
||||
TProtoHandler: ProtocolsHandler,
|
||||
{
|
||||
type InEvent = TProtoHandler::InEvent;
|
||||
type OutEvent = TProtoHandler::OutEvent;
|
||||
type Error = NodeHandlerWrapperError<TProtoHandler::Error>;
|
||||
type Substream = Substream<StreamMuxerBox>;
|
||||
pub fn inject_substream(
|
||||
&mut self,
|
||||
substream: Substream<StreamMuxerBox>,
|
||||
// The first element of the tuple is the unique upgrade identifier
|
||||
// (see `unique_dial_upgrade_id`).
|
||||
type OutboundOpenInfo = (u64, TProtoHandler::OutboundOpenInfo, Duration);
|
||||
|
||||
fn inject_substream(
|
||||
&mut self,
|
||||
substream: Self::Substream,
|
||||
endpoint: SubstreamEndpoint<Self::OutboundOpenInfo>,
|
||||
endpoint: SubstreamEndpoint<NodeHandlerWrapperOutboundOpenInfo<TProtoHandler>>,
|
||||
) {
|
||||
match endpoint {
|
||||
SubstreamEndpoint::Listener => {
|
||||
@ -315,19 +329,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_event(&mut self, event: Self::InEvent) {
|
||||
pub fn inject_event(&mut self, event: TProtoHandler::InEvent) {
|
||||
self.handler.inject_event(event);
|
||||
}
|
||||
|
||||
fn inject_address_change(&mut self, new_address: &Multiaddr) {
|
||||
pub fn inject_address_change(&mut self, new_address: &Multiaddr) {
|
||||
self.handler.inject_address_change(new_address);
|
||||
}
|
||||
|
||||
fn poll(
|
||||
pub fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<ConnectionHandlerEvent<Self::OutboundOpenInfo, Self::OutEvent>, Self::Error>>
|
||||
{
|
||||
) -> Poll<
|
||||
Result<
|
||||
NodeHandlerWrapperEvent<
|
||||
NodeHandlerWrapperOutboundOpenInfo<TProtoHandler>,
|
||||
TProtoHandler::OutEvent,
|
||||
>,
|
||||
NodeHandlerWrapperError<TProtoHandler::Error>,
|
||||
>,
|
||||
> {
|
||||
while let Poll::Ready(Some((user_data, res))) = self.negotiating_in.poll_next_unpin(cx) {
|
||||
match res {
|
||||
Ok(upgrade) => self
|
||||
@ -372,7 +393,7 @@ where
|
||||
|
||||
match poll_result {
|
||||
Poll::Ready(ProtocolsHandlerEvent::Custom(event)) => {
|
||||
return Poll::Ready(Ok(ConnectionHandlerEvent::Custom(event)));
|
||||
return Poll::Ready(Ok(NodeHandlerWrapperEvent::Custom(event)));
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
let id = self.unique_dial_upgrade_id;
|
||||
@ -380,7 +401,7 @@ where
|
||||
self.unique_dial_upgrade_id += 1;
|
||||
let (upgrade, info) = protocol.into_upgrade();
|
||||
self.queued_dial_upgrades.push((id, SendWrapper(upgrade)));
|
||||
return Poll::Ready(Ok(ConnectionHandlerEvent::OutboundSubstreamRequest((
|
||||
return Poll::Ready(Ok(NodeHandlerWrapperEvent::OutboundSubstreamRequest((
|
||||
id, info, timeout,
|
||||
))));
|
||||
}
|
||||
@ -408,3 +429,13 @@ where
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
/// Event produced by a [`NodeHandlerWrapper`].
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum NodeHandlerWrapperEvent<TOutboundOpenInfo, TCustom> {
|
||||
/// Require a new outbound substream to be opened with the remote.
|
||||
OutboundSubstreamRequest(TOutboundOpenInfo),
|
||||
|
||||
/// Other event.
|
||||
Custom(TCustom),
|
||||
}
|
||||
|
Reference in New Issue
Block a user