mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-28 17:21:34 +00:00
replace Vec with FuturesUnordered (#163)
* replace Vec with FuturesUnordered * add err log
This commit is contained in:
committed by
Pierre Krieger
parent
2445d9e9ee
commit
96747441fc
@ -42,6 +42,7 @@
|
||||
use fnv::FnvHashMap;
|
||||
use futures::future::{self, FutureResult, IntoFuture};
|
||||
use futures::{Async, Future, Poll, Stream};
|
||||
use futures::stream::FuturesUnordered;
|
||||
use futures::stream::Fuse as StreamFuse;
|
||||
use futures::sync::mpsc;
|
||||
use multiaddr::Multiaddr;
|
||||
@ -141,7 +142,7 @@ where
|
||||
let listener = ConnectionReuseListener {
|
||||
shared: self.shared.clone(),
|
||||
listener: listener.fuse(),
|
||||
current_upgrades: Vec::new(),
|
||||
current_upgrades: FuturesUnordered::new(),
|
||||
connections: Vec::new(),
|
||||
};
|
||||
|
||||
@ -233,7 +234,7 @@ where
|
||||
{
|
||||
// The main listener. `S` is from the underlying transport.
|
||||
listener: StreamFuse<S>,
|
||||
current_upgrades: Vec<F>,
|
||||
current_upgrades: FuturesUnordered<F>,
|
||||
connections: Vec<(M, <M as StreamMuxer>::InboundSubstream, Multiaddr)>,
|
||||
|
||||
// Shared between the whole connection reuse mechanism.
|
||||
@ -272,13 +273,10 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
// Check whether any upgrade (to a muxer) on an incoming connection is ready.
|
||||
// We extract everything at the start, then insert back the elements that we still want at
|
||||
// the next iteration.
|
||||
for n in (0..self.current_upgrades.len()).rev() {
|
||||
let mut current_upgrade = self.current_upgrades.swap_remove(n);
|
||||
match current_upgrade.poll() {
|
||||
Ok(Async::Ready((muxer, client_addr))) => {
|
||||
match self.current_upgrades.poll() {
|
||||
Ok(Async::Ready(Some((muxer, client_addr)))) => {
|
||||
let next_incoming = muxer.clone().inbound();
|
||||
self.connections
|
||||
.push((muxer.clone(), next_incoming, client_addr.clone()));
|
||||
@ -289,16 +287,13 @@ where
|
||||
.active_connections
|
||||
.insert(client_addr, muxer);
|
||||
}
|
||||
Ok(Async::NotReady) => {
|
||||
self.current_upgrades.push(current_upgrade);
|
||||
}
|
||||
Err(err) => {
|
||||
// Insert the rest of the pending upgrades, but not the current one.
|
||||
debug!(target: "libp2p-swarm", "error while upgrading listener connection: \
|
||||
{:?}", err);
|
||||
return Ok(Async::Ready(Some(future::err(err))));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Check whether any incoming substream is ready.
|
||||
|
@ -21,6 +21,7 @@
|
||||
use std::fmt;
|
||||
use std::io::Error as IoError;
|
||||
use futures::{future, Async, Future, IntoFuture, Poll, Stream};
|
||||
use futures::stream::{FuturesUnordered, StreamFuture};
|
||||
use futures::sync::mpsc;
|
||||
use {ConnectionUpgrade, Multiaddr, MuxedTransport, UpgradedNode};
|
||||
|
||||
@ -55,11 +56,11 @@ where
|
||||
handler: handler,
|
||||
new_listeners: new_listeners_rx,
|
||||
next_incoming: upgraded.clone().next_incoming(),
|
||||
listeners: Vec::new(),
|
||||
listeners_upgrade: Vec::new(),
|
||||
dialers: Vec::new(),
|
||||
listeners: FuturesUnordered::new(),
|
||||
listeners_upgrade: FuturesUnordered::new(),
|
||||
dialers: FuturesUnordered::new(),
|
||||
new_dialers: new_dialers_rx,
|
||||
to_process: Vec::new(),
|
||||
to_process: FuturesUnordered::new(),
|
||||
new_toprocess: new_toprocess_rx,
|
||||
};
|
||||
|
||||
@ -222,7 +223,8 @@ where
|
||||
next_incoming: Box<
|
||||
Future<Item = Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>, Error = IoError>,
|
||||
>,
|
||||
listeners: Vec<
|
||||
listeners: FuturesUnordered<
|
||||
StreamFuture<
|
||||
Box<
|
||||
Stream<
|
||||
Item = Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>,
|
||||
@ -230,11 +232,13 @@ where
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
listeners_upgrade: Vec<Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>>,
|
||||
dialers: Vec<Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>>,
|
||||
>,
|
||||
listeners_upgrade:
|
||||
FuturesUnordered<Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>>,
|
||||
dialers: FuturesUnordered<Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>>,
|
||||
new_dialers:
|
||||
mpsc::UnboundedReceiver<Box<Future<Item = (C::Output, Multiaddr), Error = IoError>>>,
|
||||
to_process: Vec<future::Either<F, Box<Future<Item = (), Error = IoError>>>>,
|
||||
to_process: FuturesUnordered<future::Either<F, Box<Future<Item = (), Error = IoError>>>>,
|
||||
new_toprocess: mpsc::UnboundedReceiver<Box<Future<Item = (), Error = IoError>>>,
|
||||
}
|
||||
|
||||
@ -270,7 +274,7 @@ where
|
||||
|
||||
match self.new_listeners.poll() {
|
||||
Ok(Async::Ready(Some(new_listener))) => {
|
||||
self.listeners.push(new_listener);
|
||||
self.listeners.push(new_listener.into_future());
|
||||
}
|
||||
Ok(Async::Ready(None)) | Err(_) => {
|
||||
// New listener sender has been closed.
|
||||
@ -298,29 +302,20 @@ where
|
||||
Ok(Async::NotReady) => {}
|
||||
};
|
||||
|
||||
for n in (0..self.listeners.len()).rev() {
|
||||
let mut listener = self.listeners.swap_remove(n);
|
||||
match listener.poll() {
|
||||
Ok(Async::Ready(Some(upgrade))) => {
|
||||
trace!(target: "libp2p-swarm", "Swarm received new connection on \
|
||||
listener socket");
|
||||
self.listeners.push(listener);
|
||||
match self.listeners.poll() {
|
||||
Ok(Async::Ready(Some((Some(upgrade), remaining)))) => {
|
||||
trace!(target: "libp2p-swarm", "Swarm received new connection on listener socket");
|
||||
self.listeners_upgrade.push(upgrade);
|
||||
self.listeners.push(remaining.into_future());
|
||||
}
|
||||
Ok(Async::NotReady) => {
|
||||
self.listeners.push(listener);
|
||||
}
|
||||
Ok(Async::Ready(None)) => {}
|
||||
Err(err) => {
|
||||
Err((err, _)) => {
|
||||
warn!(target: "libp2p-swarm", "Error in listener: {:?}", err);
|
||||
}
|
||||
};
|
||||
_ => {}
|
||||
}
|
||||
|
||||
for n in (0..self.listeners_upgrade.len()).rev() {
|
||||
let mut upgrade = self.listeners_upgrade.swap_remove(n);
|
||||
match upgrade.poll() {
|
||||
Ok(Async::Ready((output, client_addr))) => {
|
||||
match self.listeners_upgrade.poll() {
|
||||
Ok(Async::Ready(Some((output, client_addr)))) => {
|
||||
debug!(
|
||||
"Successfully upgraded incoming connection with {}",
|
||||
client_addr
|
||||
@ -329,44 +324,32 @@ where
|
||||
handler(output, client_addr).into_future(),
|
||||
));
|
||||
}
|
||||
Ok(Async::NotReady) => {
|
||||
self.listeners_upgrade.push(upgrade);
|
||||
}
|
||||
Err(err) => {
|
||||
debug!(target: "libp2p-swarm", "Error in listener upgrade: {:?}", err);
|
||||
}
|
||||
warn!(target: "libp2p-swarm", "Error in listener upgrade: {:?}", err);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
for n in (0..self.dialers.len()).rev() {
|
||||
let mut dialer = self.dialers.swap_remove(n);
|
||||
match dialer.poll() {
|
||||
Ok(Async::Ready((output, addr))) => {
|
||||
match self.dialers.poll() {
|
||||
Ok(Async::Ready(Some((output, addr)))) => {
|
||||
trace!("Successfully upgraded dialed connection with {}", addr);
|
||||
self.to_process
|
||||
.push(future::Either::A(handler(output, addr).into_future()));
|
||||
}
|
||||
Ok(Async::NotReady) => {
|
||||
self.dialers.push(dialer);
|
||||
}
|
||||
Err(err) => {
|
||||
debug!(target: "libp2p-swarm", "Error in dialer upgrade: {:?}", err);
|
||||
}
|
||||
warn!(target: "libp2p-swarm", "Error in dialer upgrade: {:?}", err);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
for n in (0..self.to_process.len()).rev() {
|
||||
let mut to_process = self.to_process.swap_remove(n);
|
||||
match to_process.poll() {
|
||||
Ok(Async::Ready(())) => {
|
||||
trace!(target: "libp2p-swarm", "Future returned by swarm handler driven to \
|
||||
completion");
|
||||
match self.to_process.poll() {
|
||||
Ok(Async::Ready(Some(()))) => {
|
||||
trace!(target: "libp2p-swarm", "Future returned by swarm handler driven to completion");
|
||||
}
|
||||
Ok(Async::NotReady) => self.to_process.push(to_process),
|
||||
Err(err) => {
|
||||
debug!(target: "libp2p-swarm", "Error in processing: {:?}", err);
|
||||
}
|
||||
warn!(target: "libp2p-swarm", "Error in processing: {:?}", err);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// TODO: we never return `Ok(Ready)` because there's no way to know whether
|
||||
|
Reference in New Issue
Block a user