mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-29 01:31:33 +00:00
Split ConnectionUpgrade
. (#642)
Introduce `InboundUpgrade` and `OutboundUpgrade`.
This commit is contained in:
committed by
Pierre Krieger
parent
466385a58a
commit
2e549884ef
@ -19,8 +19,9 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use bytes::{BufMut, Bytes, BytesMut};
|
||||
use futures::{prelude::*, future::FutureResult, future::IntoFuture};
|
||||
use libp2p_core::{ConnectionUpgrade, Endpoint};
|
||||
use futures::{prelude::*, future::{self, FutureResult}, try_ready};
|
||||
use libp2p_core::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
|
||||
use log::debug;
|
||||
use rand::{distributions::Standard, prelude::*, rngs::EntropyRng};
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Error as IoError;
|
||||
@ -42,71 +43,53 @@ impl<TUserData> Default for Ping<TUserData> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Output of a `Ping` upgrade.
|
||||
pub enum PingOutput<TSocket, TUserData> {
|
||||
/// We are on the dialing side.
|
||||
Pinger(PingDialer<TSocket, TUserData>),
|
||||
/// We are on the listening side.
|
||||
Ponger(PingListener<TSocket>),
|
||||
}
|
||||
impl<TUserData> UpgradeInfo for Ping<TUserData> {
|
||||
type UpgradeId = ();
|
||||
type NamesIter = iter::Once<(Bytes, Self::UpgradeId)>;
|
||||
|
||||
impl<TSocket, TUserData> ConnectionUpgrade<TSocket> for Ping<TUserData>
|
||||
where
|
||||
TSocket: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
||||
type UpgradeIdentifier = ();
|
||||
|
||||
#[inline]
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
iter::once(("/ipfs/ping/1.0.0".into(), ()))
|
||||
}
|
||||
}
|
||||
|
||||
type Output = PingOutput<TSocket, TUserData>;
|
||||
type Future = FutureResult<Self::Output, IoError>;
|
||||
impl<TSocket, TUserData> InboundUpgrade<TSocket> for Ping<TUserData>
|
||||
where
|
||||
TSocket: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type Output = PingListener<TSocket>;
|
||||
type Error = IoError;
|
||||
type Future = FutureResult<Self::Output, Self::Error>;
|
||||
|
||||
#[inline]
|
||||
fn upgrade(
|
||||
self,
|
||||
socket: TSocket,
|
||||
_: Self::UpgradeIdentifier,
|
||||
endpoint: Endpoint,
|
||||
) -> Self::Future {
|
||||
let out = match endpoint {
|
||||
Endpoint::Dialer => upgrade_as_dialer(socket),
|
||||
Endpoint::Listener => upgrade_as_listener(socket),
|
||||
fn upgrade_inbound(self, socket: TSocket, _: Self::UpgradeId) -> Self::Future {
|
||||
let listener = PingListener {
|
||||
inner: Framed::new(socket, Codec),
|
||||
state: PingListenerState::Listening,
|
||||
};
|
||||
|
||||
Ok(out).into_future()
|
||||
future::ok(listener)
|
||||
}
|
||||
}
|
||||
|
||||
/// Upgrades a connection from the dialer side.
|
||||
fn upgrade_as_dialer<TSocket, TUserData>(socket: TSocket) -> PingOutput<TSocket, TUserData>
|
||||
where TSocket: AsyncRead + AsyncWrite,
|
||||
impl<TSocket, TUserData> OutboundUpgrade<TSocket> for Ping<TUserData>
|
||||
where
|
||||
TSocket: AsyncRead + AsyncWrite,
|
||||
{
|
||||
let dialer = PingDialer {
|
||||
inner: Framed::new(socket, Codec),
|
||||
need_writer_flush: false,
|
||||
needs_close: false,
|
||||
sent_pings: VecDeque::with_capacity(4),
|
||||
rng: EntropyRng::default(),
|
||||
pings_to_send: VecDeque::with_capacity(4),
|
||||
};
|
||||
type Output = PingDialer<TSocket, TUserData>;
|
||||
type Error = IoError;
|
||||
type Future = FutureResult<Self::Output, Self::Error>;
|
||||
|
||||
PingOutput::Pinger(dialer)
|
||||
}
|
||||
|
||||
/// Upgrades a connection from the listener side.
|
||||
fn upgrade_as_listener<TSocket, TUserData>(socket: TSocket) -> PingOutput<TSocket, TUserData>
|
||||
where TSocket: AsyncRead + AsyncWrite,
|
||||
{
|
||||
let listener = PingListener {
|
||||
inner: Framed::new(socket, Codec),
|
||||
state: PingListenerState::Listening,
|
||||
};
|
||||
|
||||
PingOutput::Ponger(listener)
|
||||
#[inline]
|
||||
fn upgrade_outbound(self, socket: TSocket, _: Self::UpgradeId) -> Self::Future {
|
||||
let dialer = PingDialer {
|
||||
inner: Framed::new(socket, Codec),
|
||||
need_writer_flush: false,
|
||||
needs_close: false,
|
||||
sent_pings: VecDeque::with_capacity(4),
|
||||
rng: EntropyRng::default(),
|
||||
pings_to_send: VecDeque::with_capacity(4),
|
||||
};
|
||||
future::ok(dialer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends pings and receives the pongs.
|
||||
@ -342,9 +325,9 @@ mod tests {
|
||||
|
||||
use self::tokio_tcp::TcpListener;
|
||||
use self::tokio_tcp::TcpStream;
|
||||
use super::{Ping, PingOutput};
|
||||
use super::Ping;
|
||||
use futures::{Future, Stream};
|
||||
use libp2p_core::{ConnectionUpgrade, Endpoint};
|
||||
use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade};
|
||||
|
||||
// TODO: rewrite tests with the MemoryTransport
|
||||
|
||||
@ -358,32 +341,18 @@ mod tests {
|
||||
.into_future()
|
||||
.map_err(|(e, _)| e.into())
|
||||
.and_then(|(c, _)| {
|
||||
Ping::<()>::default().upgrade(
|
||||
c.unwrap(),
|
||||
(),
|
||||
Endpoint::Listener,
|
||||
)
|
||||
Ping::<()>::default().upgrade_inbound(c.unwrap(), ())
|
||||
})
|
||||
.and_then(|out| match out {
|
||||
PingOutput::Ponger(service) => service,
|
||||
_ => unreachable!(),
|
||||
});
|
||||
.flatten();
|
||||
|
||||
let client = TcpStream::connect(&listener_addr)
|
||||
.map_err(|e| e.into())
|
||||
.and_then(|c| {
|
||||
Ping::<()>::default().upgrade(
|
||||
c,
|
||||
(),
|
||||
Endpoint::Dialer,
|
||||
)
|
||||
Ping::<()>::default().upgrade_outbound(c, ())
|
||||
})
|
||||
.and_then(|out| match out {
|
||||
PingOutput::Pinger(mut pinger) => {
|
||||
pinger.ping(());
|
||||
pinger.into_future().map(|_| ()).map_err(|_| panic!())
|
||||
},
|
||||
_ => unreachable!(),
|
||||
.and_then(|mut pinger| {
|
||||
pinger.ping(());
|
||||
pinger.into_future().map(|_| ()).map_err(|_| panic!())
|
||||
})
|
||||
.map(|_| ());
|
||||
|
||||
@ -402,39 +371,23 @@ mod tests {
|
||||
.into_future()
|
||||
.map_err(|(e, _)| e.into())
|
||||
.and_then(|(c, _)| {
|
||||
Ping::<u32>::default().upgrade(
|
||||
c.unwrap(),
|
||||
(),
|
||||
Endpoint::Listener,
|
||||
)
|
||||
Ping::<u32>::default().upgrade_inbound(c.unwrap(), ())
|
||||
})
|
||||
.and_then(|out| match out {
|
||||
PingOutput::Ponger(service) => service,
|
||||
_ => unreachable!(),
|
||||
});
|
||||
.flatten();
|
||||
|
||||
let client = TcpStream::connect(&listener_addr)
|
||||
.map_err(|e| e.into())
|
||||
.and_then(|c| {
|
||||
Ping::<u32>::default().upgrade(
|
||||
c,
|
||||
(),
|
||||
Endpoint::Dialer,
|
||||
)
|
||||
Ping::<u32>::default().upgrade_outbound(c, ())
|
||||
})
|
||||
.and_then(|out| match out {
|
||||
PingOutput::Pinger(mut pinger) => {
|
||||
for n in 0..20 {
|
||||
pinger.ping(n);
|
||||
}
|
||||
|
||||
pinger
|
||||
.take(20)
|
||||
.collect()
|
||||
.map(|val| { assert_eq!(val, (0..20).collect::<Vec<_>>()); })
|
||||
.map_err(|_| panic!())
|
||||
},
|
||||
_ => unreachable!(),
|
||||
.and_then(|mut pinger| {
|
||||
for n in 0..20 {
|
||||
pinger.ping(n);
|
||||
}
|
||||
pinger.take(20)
|
||||
.collect()
|
||||
.map(|val| { assert_eq!(val, (0..20).collect::<Vec<_>>()); })
|
||||
.map_err(|_| panic!())
|
||||
});
|
||||
|
||||
let mut runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
|
Reference in New Issue
Block a user