Add post-grace peer recovery coordinator
This commit is contained in:
+21
-2
@@ -5,7 +5,7 @@ use iroh_gossip::proto::TopicId;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use async_trait::async_trait;
|
||||
use tokio_stream::StreamExt;
|
||||
use serde::{Serialize, Deserialize};
|
||||
@@ -198,6 +198,10 @@ pub struct IrohGossipState {
|
||||
secret_key: SecretKey,
|
||||
self_state: Arc<Mutex<Option<PeerState>>>,
|
||||
peers: Arc<Mutex<HashMap<EndpointId, PeerState>>>,
|
||||
/// Previously verified peers whose live roster entry was removed by a
|
||||
/// transient disconnect. Retained only so a later authenticated `Leave`
|
||||
/// still reaches core and cancels background recovery.
|
||||
disconnected_peers: Arc<Mutex<HashSet<EndpointId>>>,
|
||||
event_tx: mpsc::Sender<RoomEvent>,
|
||||
event_rx: Mutex<Option<mpsc::Receiver<RoomEvent>>>,
|
||||
active_topic: Mutex<Option<tokio::task::JoinHandle<()>>>,
|
||||
@@ -223,6 +227,7 @@ impl IrohGossipState {
|
||||
secret_key,
|
||||
self_state: Arc::new(Mutex::new(None)),
|
||||
peers: Arc::new(Mutex::new(HashMap::new())),
|
||||
disconnected_peers: Arc::new(Mutex::new(HashSet::new())),
|
||||
event_tx,
|
||||
event_rx: Mutex::new(Some(event_rx)),
|
||||
active_topic: Mutex::new(None),
|
||||
@@ -295,6 +300,7 @@ impl RoomState for IrohGossipState {
|
||||
|
||||
let event_tx = self.event_tx.clone();
|
||||
let peers = self.peers.clone();
|
||||
let disconnected_peers = self.disconnected_peers.clone();
|
||||
let address_lookup = self.address_lookup.clone();
|
||||
let self_state_clone = self.self_state.clone();
|
||||
let gossip_sender_clone = gossip_sender.clone();
|
||||
@@ -393,6 +399,7 @@ impl RoomState for IrohGossipState {
|
||||
// peer-supplied: cap/validate once at ingest
|
||||
// so invalid offers never render a Watch button.
|
||||
state.sharing = state.sharing.and_then(crate::screenshare::sanitize_ticket);
|
||||
disconnected_peers.lock().unwrap().remove(&payload.author);
|
||||
let (is_new, state_changed) = {
|
||||
let mut peer_map = peers.lock().unwrap();
|
||||
let is_new = !peer_map.contains_key(&payload.author);
|
||||
@@ -423,7 +430,11 @@ impl RoomState for IrohGossipState {
|
||||
GossipMessage::Leave => {
|
||||
crate::log_msg(&format!("Gossip peer leave request from author={:?}", payload.author));
|
||||
let removed = peers.lock().unwrap().remove(&payload.author).is_some();
|
||||
if removed {
|
||||
let was_disconnected = disconnected_peers
|
||||
.lock()
|
||||
.unwrap()
|
||||
.remove(&payload.author);
|
||||
if removed || was_disconnected {
|
||||
let _ = event_tx.send(RoomEvent::PeerLeft(payload.author)).await;
|
||||
}
|
||||
}
|
||||
@@ -472,6 +483,7 @@ impl RoomState for IrohGossipState {
|
||||
// cached presence entry; a rejoin re-announces as new.
|
||||
let removed = peers.lock().unwrap().remove(&peer_id).is_some();
|
||||
if removed {
|
||||
disconnected_peers.lock().unwrap().insert(peer_id);
|
||||
crate::log_msg(&format!("Peer connection lost (NeighborDown): {:?}", peer_id));
|
||||
let _ = event_tx.send(RoomEvent::PeerConnectionLost(peer_id)).await;
|
||||
}
|
||||
@@ -547,6 +559,12 @@ impl RoomState for IrohGossipState {
|
||||
.map_err(|e| NetError::Gossip(e.to_string()))
|
||||
}
|
||||
|
||||
fn mark_peer_disconnected(&self, peer_id: EndpointId) {
|
||||
if self.peers.lock().unwrap().remove(&peer_id).is_some() {
|
||||
self.disconnected_peers.lock().unwrap().insert(peer_id);
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_chat(&self, text: String) -> Result<(), NetError> {
|
||||
let name = {
|
||||
let guard = self.self_state.lock().unwrap();
|
||||
@@ -602,6 +620,7 @@ impl RoomState for IrohGossipState {
|
||||
}
|
||||
|
||||
self.peers.lock().unwrap().clear();
|
||||
self.disconnected_peers.lock().unwrap().clear();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user