Skip to content

Commit 62622a1

Browse files
authored
core/src/transport: Poll Transport directly, remove Transport::Listener (#2652)
Remove the concept of individual `Transport::Listener` streams from `Transport`. Instead the `Transport` is polled directly via `Transport::poll`. The `Transport` is now responsible for driving its listeners.
1 parent b28cdb3 commit 62622a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2070
-2020
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ default = [
3535
"websocket",
3636
"yamux",
3737
]
38+
3839
autonat = ["dep:libp2p-autonat"]
3940
dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"]
4041
deflate = ["dep:libp2p-deflate"]

core/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
in favor of forcing `StreamMuxer::Substream` to implement `AsyncRead + AsyncWrite`. See [PR 2707].
66
- Replace `Into<std::io::Error>` bound on `StreamMuxer::Error` with `std::error::Error`. See [PR 2710].
77

8+
- Remove the concept of individual `Transport::Listener` streams from `Transport`.
9+
Instead the `Transport` is polled directly via `Transport::poll`. The
10+
`Transport` is now responsible for driving its listeners. See [PR 2652].
11+
812
[PR 2691]: https://github.com/libp2p/rust-libp2p/pull/2691
913
[PR 2707]: https://github.com/libp2p/rust-libp2p/pull/2707
1014
[PR 2710]: https://github.com/libp2p/rust-libp2p/pull/2710
15+
[PR 2652]: https://github.com/libp2p/rust-libp2p/pull/2652
1116

1217
# 0.33.0
1318

core/src/connection.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,6 @@ impl std::ops::Add<usize> for ConnectionId {
4343
}
4444
}
4545

46-
/// The ID of a single listener.
47-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
48-
pub struct ListenerId(u64);
49-
50-
impl ListenerId {
51-
/// Creates a `ListenerId` from a non-negative integer.
52-
pub fn new(id: u64) -> Self {
53-
Self(id)
54-
}
55-
}
56-
57-
impl std::ops::Add<u64> for ListenerId {
58-
type Output = Self;
59-
60-
fn add(self, other: u64) -> Self {
61-
Self(self.0 + other)
62-
}
63-
}
64-
6546
/// The endpoint roles associated with a peer-to-peer communication channel.
6647
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
6748
pub enum Endpoint {

core/src/either.rs

Lines changed: 46 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
use crate::{
2222
muxing::{StreamMuxer, StreamMuxerEvent},
23-
transport::{ListenerEvent, Transport, TransportError},
23+
transport::{ListenerId, Transport, TransportError, TransportEvent},
2424
Multiaddr, ProtocolName,
2525
};
2626
use futures::{
@@ -274,48 +274,6 @@ pub enum EitherOutbound<A: StreamMuxer, B: StreamMuxer> {
274274
B(B::OutboundSubstream),
275275
}
276276

277-
/// Implements `Stream` and dispatches all method calls to either `First` or `Second`.
278-
#[pin_project(project = EitherListenStreamProj)]
279-
#[derive(Debug, Copy, Clone)]
280-
#[must_use = "futures do nothing unless polled"]
281-
pub enum EitherListenStream<A, B> {
282-
First(#[pin] A),
283-
Second(#[pin] B),
284-
}
285-
286-
impl<AStream, BStream, AInner, BInner, AError, BError> Stream
287-
for EitherListenStream<AStream, BStream>
288-
where
289-
AStream: TryStream<Ok = ListenerEvent<AInner, AError>, Error = AError>,
290-
BStream: TryStream<Ok = ListenerEvent<BInner, BError>, Error = BError>,
291-
{
292-
type Item = Result<
293-
ListenerEvent<EitherFuture<AInner, BInner>, EitherError<AError, BError>>,
294-
EitherError<AError, BError>,
295-
>;
296-
297-
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
298-
match self.project() {
299-
EitherListenStreamProj::First(a) => match TryStream::try_poll_next(a, cx) {
300-
Poll::Pending => Poll::Pending,
301-
Poll::Ready(None) => Poll::Ready(None),
302-
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le
303-
.map(EitherFuture::First)
304-
.map_err(EitherError::A)))),
305-
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::A(err)))),
306-
},
307-
EitherListenStreamProj::Second(a) => match TryStream::try_poll_next(a, cx) {
308-
Poll::Pending => Poll::Pending,
309-
Poll::Ready(None) => Poll::Ready(None),
310-
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le
311-
.map(EitherFuture::Second)
312-
.map_err(EitherError::B)))),
313-
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::B(err)))),
314-
},
315-
}
316-
}
317-
}
318-
319277
/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
320278
#[pin_project(project = EitherFutureProj)]
321279
#[derive(Debug, Copy, Clone)]
@@ -385,11 +343,12 @@ impl<A: ProtocolName, B: ProtocolName> ProtocolName for EitherName<A, B> {
385343
}
386344
}
387345
}
388-
389-
#[derive(Debug, Copy, Clone)]
346+
#[pin_project(project = EitherTransportProj)]
347+
#[derive(Debug)]
348+
#[must_use = "transports do nothing unless polled"]
390349
pub enum EitherTransport<A, B> {
391-
Left(A),
392-
Right(B),
350+
Left(#[pin] A),
351+
Right(#[pin] B),
393352
}
394353

395354
impl<A, B> Transport for EitherTransport<A, B>
@@ -399,29 +358,54 @@ where
399358
{
400359
type Output = EitherOutput<A::Output, B::Output>;
401360
type Error = EitherError<A::Error, B::Error>;
402-
type Listener = EitherListenStream<A::Listener, B::Listener>;
403361
type ListenerUpgrade = EitherFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
404362
type Dial = EitherFuture<A::Dial, B::Dial>;
405363

406-
fn listen_on(
407-
&mut self,
408-
addr: Multiaddr,
409-
) -> Result<Self::Listener, TransportError<Self::Error>> {
410-
use TransportError::*;
411-
match self {
412-
EitherTransport::Left(a) => match a.listen_on(addr) {
413-
Ok(listener) => Ok(EitherListenStream::First(listener)),
414-
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
415-
Err(Other(err)) => Err(Other(EitherError::A(err))),
364+
fn poll(
365+
self: Pin<&mut Self>,
366+
cx: &mut Context<'_>,
367+
) -> Poll<TransportEvent<Self::ListenerUpgrade, Self::Error>> {
368+
match self.project() {
369+
EitherTransportProj::Left(a) => match a.poll(cx) {
370+
Poll::Pending => Poll::Pending,
371+
Poll::Ready(event) => Poll::Ready(
372+
event
373+
.map_upgrade(EitherFuture::First)
374+
.map_err(EitherError::A),
375+
),
416376
},
417-
EitherTransport::Right(b) => match b.listen_on(addr) {
418-
Ok(listener) => Ok(EitherListenStream::Second(listener)),
419-
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
420-
Err(Other(err)) => Err(Other(EitherError::B(err))),
377+
EitherTransportProj::Right(b) => match b.poll(cx) {
378+
Poll::Pending => Poll::Pending,
379+
Poll::Ready(event) => Poll::Ready(
380+
event
381+
.map_upgrade(EitherFuture::Second)
382+
.map_err(EitherError::B),
383+
),
421384
},
422385
}
423386
}
424387

388+
fn remove_listener(&mut self, id: ListenerId) -> bool {
389+
match self {
390+
EitherTransport::Left(t) => t.remove_listener(id),
391+
EitherTransport::Right(t) => t.remove_listener(id),
392+
}
393+
}
394+
395+
fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<Self::Error>> {
396+
use TransportError::*;
397+
match self {
398+
EitherTransport::Left(a) => a.listen_on(addr).map_err(|e| match e {
399+
MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr),
400+
Other(err) => Other(EitherError::A(err)),
401+
}),
402+
EitherTransport::Right(b) => b.listen_on(addr).map_err(|e| match e {
403+
MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr),
404+
Other(err) => Other(EitherError::B(err)),
405+
}),
406+
}
407+
}
408+
425409
fn dial(&mut self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
426410
use TransportError::*;
427411
match self {

0 commit comments

Comments
 (0)