use peer center instance to gatter peers info (#21)

* use peer center instance to gatter peers info
This commit is contained in:
Sijie.Sun
2024-02-29 00:04:48 +08:00
committed by GitHub
parent 31af413b03
commit 24178bcf6e
8 changed files with 291 additions and 65 deletions
+44 -6
View File
@@ -5,12 +5,12 @@ use std::{
use dashmap::DashMap;
use once_cell::sync::Lazy;
use tokio::sync::RwLock;
use tokio::{sync::RwLock, task::JoinSet};
use crate::peers::PeerId;
use super::{
service::{GlobalPeerMap, PeerCenterService, PeerInfoForGlobalMap},
service::{GetGlobalPeerMapResponse, GlobalPeerMap, PeerCenterService, PeerInfoForGlobalMap},
Digest, Error,
};
@@ -18,6 +18,7 @@ pub(crate) struct PeerCenterServerGlobalData {
pub global_peer_map: GlobalPeerMap,
pub digest: Digest,
pub update_time: std::time::Instant,
pub peer_update_time: DashMap<PeerId, std::time::Instant>,
}
impl PeerCenterServerGlobalData {
@@ -26,6 +27,7 @@ impl PeerCenterServerGlobalData {
global_peer_map: GlobalPeerMap::new(),
digest: Digest::default(),
update_time: std::time::Instant::now(),
peer_update_time: DashMap::new(),
}
}
}
@@ -47,13 +49,41 @@ pub struct PeerCenterServer {
// every peer has its own server, so use per-struct dash map is ok.
my_node_id: PeerId,
digest_map: DashMap<PeerId, Digest>,
tasks: Arc<JoinSet<()>>,
}
impl PeerCenterServer {
pub fn new(my_node_id: PeerId) -> Self {
let mut tasks = JoinSet::new();
tasks.spawn(async move {
loop {
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
PeerCenterServer::clean_outdated_peer(my_node_id).await;
}
});
PeerCenterServer {
my_node_id,
digest_map: DashMap::new(),
tasks: Arc::new(tasks),
}
}
async fn clean_outdated_peer(my_node_id: PeerId) {
let data = get_global_data(my_node_id);
let mut locked_data = data.write().await;
let now = std::time::Instant::now();
let mut to_remove = Vec::new();
for kv in locked_data.peer_update_time.iter() {
if now.duration_since(*kv.value()).as_secs() > 10 {
to_remove.push(*kv.key());
}
}
for peer_id in to_remove {
locked_data.global_peer_map.map.remove(&peer_id);
locked_data.peer_update_time.remove(&peer_id);
}
}
}
@@ -70,6 +100,12 @@ impl PeerCenterService for PeerCenterServer {
) -> Result<(), Error> {
tracing::warn!("receive report_peers");
let data = get_global_data(self.my_node_id);
let mut locked_data = data.write().await;
locked_data
.peer_update_time
.insert(my_peer_id, std::time::Instant::now());
let old_digest = self.digest_map.get(&my_peer_id);
// if digest match, no need to update
if let Some(old_digest) = old_digest {
@@ -83,8 +119,6 @@ impl PeerCenterService for PeerCenterServer {
}
self.digest_map.insert(my_peer_id, digest);
let data = get_global_data(self.my_node_id);
let mut locked_data = data.write().await;
locked_data
.global_peer_map
.map
@@ -93,6 +127,7 @@ impl PeerCenterService for PeerCenterServer {
let mut hasher = std::collections::hash_map::DefaultHasher::new();
locked_data.global_peer_map.map.hash(&mut hasher);
locked_data.digest = hasher.finish() as Digest;
locked_data.update_time = std::time::Instant::now();
Ok(())
}
@@ -101,7 +136,7 @@ impl PeerCenterService for PeerCenterServer {
self,
_: tarpc::context::Context,
digest: Digest,
) -> Result<Option<GlobalPeerMap>, Error> {
) -> Result<Option<GetGlobalPeerMapResponse>, Error> {
let data = get_global_data(self.my_node_id);
if digest == data.read().await.digest {
return Ok(None);
@@ -109,6 +144,9 @@ impl PeerCenterService for PeerCenterServer {
let data = get_global_data(self.my_node_id);
let locked_data = data.read().await;
Ok(Some(locked_data.global_peer_map.clone()))
Ok(Some(GetGlobalPeerMapResponse {
global_peer_map: locked_data.global_peer_map.clone(),
digest: locked_data.digest,
}))
}
}