Replace unbounded channels with bounded ones. (#1191)

* Replace unbounded channels with bounded ones.

To remove the unbounded channels used for communicating with node tasks
an API similar to `futures::Sink` is used, i.e. sending is split into a
start and complete phase. The start phase returns `StartSend` and first
attempts to complete any pending send operations. Completing the send
means polling until `Poll::Ready(())` is returned.

In addition this PR has split the `handled_node_tasks` module into
several smaller ones (cf. `nodes::tasks`) and renamed some types:

- `nodes::handled_node_tasks::NodeTask` -> `nodes::tasks::task::Task`
- `nodes::handled_node_tasks::NodeTaskInner` -> `nodes::tasks::task::State`
- `nodes::handled_node_tasks::NodeTasks` -> `nodes::tasks::Manager`
- `nodes::handled_node_tasks::TaskClosedEvent` -> `nodes::tasks::Error`
- `nodes::handled_node_tasks::HandledNodesEvent` -> `nodes::tasks::Event`
- `nodes::handled_node_tasks::Task` -> `nodes::tasks::TaskEntry`
- `nodes::handled_node_tasks::ExtToInMessage` -> `nodes::tasks::task::ToTaskMessage`
- `nodes::handled_node_tasks::InToExtMessage` -> `nodes::tasks::task::FromTaskMessage`

* `take_over_to_complete` can be an `Option`.

Since it is always holding just a single pending message.

* `send_event_to_complete` can be an `Option`.

* Update core/src/nodes/tasks/manager.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Update core/src/nodes/tasks/manager.rs

Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>

* Add comments to explain the need to flush sends ...

of take-over and event messages delivered over Sinks.
This commit is contained in:
Toralf Wittner
2019-07-09 16:47:24 +02:00
committed by Pierre Krieger
parent a0d278a479
commit 6aba7961d1
14 changed files with 1287 additions and 806 deletions

View File

@ -137,6 +137,16 @@ where
/// List of nodes for which we deny any incoming connection.
banned_peers: HashSet<PeerId>,
/// Pending event message to be delivered.
///
/// If the pair's second element is `AsyncSink::NotReady`, the event
/// message has yet to be sent using `PeerMut::start_send_event`.
///
/// If the pair's second element is `AsyncSink::Ready`, the event
/// message has been sent and needs to be flushed using
/// `PeerMut::complete_send_event`.
send_event_to_complete: Option<(PeerId, AsyncSink<TInEvent>)>
}
impl<TTransport, TBehaviour, TInEvent, TOutEvent, THandler, THandlerErr, TConnInfo> Deref for
@ -379,6 +389,24 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
},
}
// Try to deliver pending event.
if let Some((id, pending)) = self.send_event_to_complete.take() {
if let Some(mut peer) = self.raw_swarm.peer(id.clone()).into_connected() {
if let AsyncSink::NotReady(e) = pending {
if let Ok(a@AsyncSink::NotReady(_)) = peer.start_send_event(e) {
self.send_event_to_complete = Some((id, a))
} else if let Ok(Async::NotReady) = peer.complete_send_event() {
self.send_event_to_complete = Some((id, AsyncSink::Ready))
}
} else if let Ok(Async::NotReady) = peer.complete_send_event() {
self.send_event_to_complete = Some((id, AsyncSink::Ready))
}
}
}
if self.send_event_to_complete.is_some() {
return Ok(Async::NotReady)
}
let behaviour_poll = {
let mut parameters = SwarmPollParameters {
local_peer_id: &mut self.raw_swarm.local_peer_id(),
@ -406,8 +434,12 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
}
},
Async::Ready(NetworkBehaviourAction::SendEvent { peer_id, event }) => {
if let Some(mut peer) = self.raw_swarm.peer(peer_id).into_connected() {
peer.send_event(event);
if let Some(mut peer) = self.raw_swarm.peer(peer_id.clone()).into_connected() {
if let Ok(a@AsyncSink::NotReady(_)) = peer.start_send_event(event) {
self.send_event_to_complete = Some((peer_id, a))
} else if let Ok(Async::NotReady) = peer.complete_send_event() {
self.send_event_to_complete = Some((peer_id, AsyncSink::Ready))
}
}
},
Async::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => {
@ -524,6 +556,7 @@ where TBehaviour: NetworkBehaviour,
listened_addrs: SmallVec::new(),
external_addrs: Addresses::default(),
banned_peers: HashSet::new(),
send_event_to_complete: None
}
}
}