use super::Core;
use crate::routing::{core::Proposal, error::Result, routing_api::command::Command};
use std::{collections::BTreeSet, iter, net::SocketAddr};
use xor_name::XorName;
impl Core {
pub(crate) async fn handle_peer_lost(&self, addr: &SocketAddr) -> Result<Vec<Command>> {
let name = if let Some(peer) = self.network_knowledge.find_joined_member_by_addr(addr) {
debug!("Lost known peer {}", peer);
peer.name()
} else {
trace!("Lost unknown peer {}", addr);
return Ok(vec![]);
};
if self.is_not_elder().await {
return Ok(vec![]);
}
let mut commands = self.propose_offline(name).await?;
commands.push(Command::StartConnectivityTest(name));
Ok(commands)
}
pub(crate) async fn propose_offline(&self, name: XorName) -> Result<Vec<Command>> {
self.cast_offline_proposals(&iter::once(name).collect())
.await
}
pub(crate) async fn cast_offline_proposals(
&self,
names: &BTreeSet<XorName>,
) -> Result<Vec<Command>> {
let elders: Vec<_> = self
.network_knowledge
.authority_provider()
.await
.elders()
.filter(|peer| !names.contains(&peer.name()))
.cloned()
.collect();
let mut result: Vec<Command> = Vec::new();
for name in names.iter() {
if let Some(info) = self.network_knowledge.members().get(name) {
let info = info.leave()?;
if let Ok(commands) = self
.send_proposal(elders.clone(), Proposal::Offline(info))
.await
{
result.extend(commands);
}
}
}
Ok(result)
}
}