mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-22 22:31:33 +00:00
Add IntoNodeHandler and IntoProtocolsHandler traits (#848)
* Add IntoNodeHandler * Add IntoProtocolsHandler
This commit is contained in:
@ -33,6 +33,7 @@
|
||||
//! > connection with a remote. In order to handle a protocol that requires knowledge of
|
||||
//! > the network as a whole, see the `NetworkBehaviour` trait.
|
||||
|
||||
use crate::PeerId;
|
||||
use crate::upgrade::{
|
||||
InboundUpgrade,
|
||||
OutboundUpgrade,
|
||||
@ -46,7 +47,7 @@ pub use self::dummy::DummyProtocolsHandler;
|
||||
pub use self::map_in::MapInEvent;
|
||||
pub use self::map_out::MapOutEvent;
|
||||
pub use self::node_handler::{NodeHandlerWrapper, NodeHandlerWrapperBuilder};
|
||||
pub use self::select::ProtocolsHandlerSelect;
|
||||
pub use self::select::{IntoProtocolsHandlerSelect, ProtocolsHandlerSelect};
|
||||
|
||||
mod dummy;
|
||||
mod map_in;
|
||||
@ -207,17 +208,19 @@ pub trait ProtocolsHandler {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
NodeHandlerWrapperBuilder::new(self, Duration::from_secs(10), Duration::from_secs(10), Duration::from_secs(5))
|
||||
IntoProtocolsHandler::into_node_handler_builder(self)
|
||||
}
|
||||
|
||||
/// Builds an implementation of `NodeHandler` that handles this protocol exclusively.
|
||||
///
|
||||
/// > **Note**: This is a shortcut for `self.into_node_handler_builder().build()`.
|
||||
#[inline]
|
||||
#[deprecated(note = "Use into_node_handler_builder instead")]
|
||||
fn into_node_handler(self) -> NodeHandlerWrapper<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#![allow(deprecated)]
|
||||
self.into_node_handler_builder().build()
|
||||
}
|
||||
}
|
||||
@ -353,3 +356,45 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Prototype for a `ProtocolsHandler`.
|
||||
pub trait IntoProtocolsHandler {
|
||||
/// The protocols handler.
|
||||
type Handler: ProtocolsHandler;
|
||||
|
||||
/// Builds the protocols handler.
|
||||
///
|
||||
/// The `PeerId` is the id of the node the handler is going to handle.
|
||||
fn into_handler(self, remote_peer_id: &PeerId) -> Self::Handler;
|
||||
|
||||
/// Builds an implementation of `IntoProtocolsHandler` that handles both this protocol and the
|
||||
/// other one together.
|
||||
#[inline]
|
||||
fn select<TProto2>(self, other: TProto2) -> IntoProtocolsHandlerSelect<Self, TProto2>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
IntoProtocolsHandlerSelect::new(self, other)
|
||||
}
|
||||
|
||||
/// Creates a builder that will allow creating a `NodeHandler` that handles this protocol
|
||||
/// exclusively.
|
||||
#[inline]
|
||||
fn into_node_handler_builder(self) -> NodeHandlerWrapperBuilder<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
NodeHandlerWrapperBuilder::new(self, Duration::from_secs(10), Duration::from_secs(10), Duration::from_secs(5))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoProtocolsHandler for T
|
||||
where T: ProtocolsHandler
|
||||
{
|
||||
type Handler = Self;
|
||||
|
||||
#[inline]
|
||||
fn into_handler(self, _: &PeerId) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,10 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
PeerId,
|
||||
nodes::handled_node::{NodeHandler, NodeHandlerEndpoint, NodeHandlerEvent},
|
||||
protocols_handler::{ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr},
|
||||
nodes::handled_node_tasks::IntoNodeHandler,
|
||||
protocols_handler::{ProtocolsHandler, IntoProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr},
|
||||
upgrade::{
|
||||
self,
|
||||
OutboundUpgrade,
|
||||
@ -33,12 +35,9 @@ use std::time::{Duration, Instant};
|
||||
use tokio_timer::{Delay, Timeout};
|
||||
|
||||
/// Prototype for a `NodeHandlerWrapper`.
|
||||
pub struct NodeHandlerWrapperBuilder<TProtoHandler>
|
||||
where
|
||||
TProtoHandler: ProtocolsHandler,
|
||||
{
|
||||
pub struct NodeHandlerWrapperBuilder<TIntoProtoHandler> {
|
||||
/// The underlying handler.
|
||||
handler: TProtoHandler,
|
||||
handler: TIntoProtoHandler,
|
||||
/// Timeout for incoming substreams negotiation.
|
||||
in_timeout: Duration,
|
||||
/// Timeout for outgoing substreams negotiation.
|
||||
@ -47,13 +46,13 @@ where
|
||||
useless_timeout: Duration,
|
||||
}
|
||||
|
||||
impl<TProtoHandler> NodeHandlerWrapperBuilder<TProtoHandler>
|
||||
impl<TIntoProtoHandler> NodeHandlerWrapperBuilder<TIntoProtoHandler>
|
||||
where
|
||||
TProtoHandler: ProtocolsHandler
|
||||
TIntoProtoHandler: IntoProtocolsHandler
|
||||
{
|
||||
/// Builds a `NodeHandlerWrapperBuilder`.
|
||||
#[inline]
|
||||
pub(crate) fn new(handler: TProtoHandler, in_timeout: Duration, out_timeout: Duration, useless_timeout: Duration) -> Self {
|
||||
pub(crate) fn new(handler: TIntoProtoHandler, in_timeout: Duration, out_timeout: Duration, useless_timeout: Duration) -> Self {
|
||||
NodeHandlerWrapperBuilder {
|
||||
handler,
|
||||
in_timeout,
|
||||
@ -85,8 +84,11 @@ where
|
||||
}
|
||||
|
||||
/// Builds the `NodeHandlerWrapper`.
|
||||
#[deprecated(note = "Pass the NodeHandlerWrapperBuilder directly")]
|
||||
#[inline]
|
||||
pub fn build(self) -> NodeHandlerWrapper<TProtoHandler> {
|
||||
pub fn build(self) -> NodeHandlerWrapper<TIntoProtoHandler>
|
||||
where TIntoProtoHandler: ProtocolsHandler
|
||||
{
|
||||
NodeHandlerWrapper {
|
||||
handler: self.handler,
|
||||
negotiating_in: Vec::new(),
|
||||
@ -101,6 +103,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TIntoProtoHandler, TProtoHandler> IntoNodeHandler for NodeHandlerWrapperBuilder<TIntoProtoHandler>
|
||||
where
|
||||
TIntoProtoHandler: IntoProtocolsHandler<Handler = TProtoHandler>,
|
||||
TProtoHandler: ProtocolsHandler,
|
||||
// TODO: meh for Debug
|
||||
<TProtoHandler::OutboundProtocol as OutboundUpgrade<<TProtoHandler as ProtocolsHandler>::Substream>>::Error: std::fmt::Debug
|
||||
{
|
||||
type Handler = NodeHandlerWrapper<TIntoProtoHandler::Handler>;
|
||||
|
||||
fn into_handler(self, remote_peer_id: &PeerId) -> Self::Handler {
|
||||
NodeHandlerWrapper {
|
||||
handler: self.handler.into_handler(remote_peer_id),
|
||||
negotiating_in: Vec::new(),
|
||||
negotiating_out: Vec::new(),
|
||||
in_timeout: self.in_timeout,
|
||||
out_timeout: self.out_timeout,
|
||||
queued_dial_upgrades: Vec::new(),
|
||||
unique_dial_upgrade_id: 0,
|
||||
connection_shutdown: None,
|
||||
useless_timeout: self.useless_timeout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps around an implementation of `ProtocolsHandler`, and implements `NodeHandler`.
|
||||
// TODO: add a caching system for protocols that are supported or not
|
||||
pub struct NodeHandlerWrapper<TProtoHandler>
|
||||
@ -138,6 +164,7 @@ where
|
||||
impl<TProtoHandler> NodeHandler for NodeHandlerWrapper<TProtoHandler>
|
||||
where
|
||||
TProtoHandler: ProtocolsHandler,
|
||||
// TODO: meh for Debug
|
||||
<TProtoHandler::OutboundProtocol as OutboundUpgrade<<TProtoHandler as ProtocolsHandler>::Substream>>::Error: std::fmt::Debug
|
||||
{
|
||||
type InEvent = TProtoHandler::InEvent;
|
||||
|
@ -19,9 +19,15 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
PeerId,
|
||||
either::EitherError,
|
||||
either::EitherOutput,
|
||||
protocols_handler::{ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr},
|
||||
protocols_handler::{
|
||||
IntoProtocolsHandler,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
},
|
||||
upgrade::{
|
||||
InboundUpgrade,
|
||||
OutboundUpgrade,
|
||||
@ -33,6 +39,46 @@ use crate::{
|
||||
use futures::prelude::*;
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
/// Implementation of `IntoProtocolsHandler` that combines two protocols into one.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IntoProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
proto1: TProto1,
|
||||
proto2: TProto2,
|
||||
}
|
||||
|
||||
impl<TProto1, TProto2> IntoProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
/// Builds a `IntoProtocolsHandlerSelect`.
|
||||
#[inline]
|
||||
pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self {
|
||||
IntoProtocolsHandlerSelect {
|
||||
proto1,
|
||||
proto2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<TProto1, TProto2, TSubstream> IntoProtocolsHandler for IntoProtocolsHandlerSelect<TProto1, TProto2>
|
||||
where
|
||||
TProto1: IntoProtocolsHandler,
|
||||
TProto2: IntoProtocolsHandler,
|
||||
TProto1::Handler: ProtocolsHandler<Substream = TSubstream>,
|
||||
TProto2::Handler: ProtocolsHandler<Substream = TSubstream>,
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
<TProto1::Handler as ProtocolsHandler>::InboundProtocol: InboundUpgrade<TSubstream>,
|
||||
<TProto2::Handler as ProtocolsHandler>::InboundProtocol: InboundUpgrade<TSubstream>,
|
||||
<TProto1::Handler as ProtocolsHandler>::OutboundProtocol: OutboundUpgrade<TSubstream>,
|
||||
<TProto2::Handler as ProtocolsHandler>::OutboundProtocol: OutboundUpgrade<TSubstream>
|
||||
{
|
||||
type Handler = ProtocolsHandlerSelect<TProto1::Handler, TProto2::Handler>;
|
||||
|
||||
fn into_handler(self, remote_peer_id: &PeerId) -> Self::Handler {
|
||||
ProtocolsHandlerSelect {
|
||||
proto1: self.proto1.into_handler(remote_peer_id),
|
||||
proto2: self.proto2.into_handler(remote_peer_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of `ProtocolsHandler` that combines two protocols into one.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
|
Reference in New Issue
Block a user