introduce peer center (#13)

peer_center is used to collect peer info into one peer node.

the center node is selected with the following rules:

1. has smallest peer id
2. TODO: has allow_to_be_center peer feature

peer center is not guaranteed to be stable and can be changed when peer enter
or leave.  it's used to reduce the cost to exchange infos between peers.
This commit is contained in:
Sijie.Sun
2024-02-06 13:29:12 +08:00
committed by GitHub
parent e3f2765fed
commit 7f8935a9d5
12 changed files with 542 additions and 38 deletions
+3 -7
View File
@@ -128,7 +128,7 @@ impl Debug for PeerManager {
impl PeerManager {
pub fn new(global_ctx: ArcGlobalCtx, nic_channel: mpsc::Sender<SinkItem>) -> Self {
let (packet_send, packet_recv) = mpsc::channel(100);
let peers = Arc::new(PeerMap::new(packet_send.clone()));
let peers = Arc::new(PeerMap::new(packet_send.clone(), global_ctx.clone()));
// TODO: remove these because we have impl pipeline processor.
let (peer_rpc_tspt_sender, peer_rpc_tspt_recv) = mpsc::unbounded_channel();
@@ -166,9 +166,7 @@ impl PeerManager {
peer.do_handshake_as_client().await?;
let conn_id = peer.get_conn_id();
let peer_id = peer.get_peer_id();
self.peers
.add_new_peer_conn(peer, self.global_ctx.clone())
.await;
self.peers.add_new_peer_conn(peer).await;
Ok((peer_id, conn_id))
}
@@ -189,9 +187,7 @@ impl PeerManager {
tracing::info!("add tunnel as server start");
let mut peer = PeerConn::new(self.my_node_id, self.global_ctx.clone(), tunnel);
peer.do_handshake_as_server().await?;
self.peers
.add_new_peer_conn(peer, self.global_ctx.clone())
.await;
self.peers.add_new_peer_conn(peer).await;
tracing::info!("add tunnel as server done");
Ok(())
}
+22 -3
View File
@@ -1,5 +1,6 @@
use std::sync::Arc;
use anyhow::Context;
use dashmap::DashMap;
use easytier_rpc::PeerConnInfo;
use tokio::sync::mpsc;
@@ -13,13 +14,15 @@ use crate::{
use super::{peer::Peer, peer_conn::PeerConn, route_trait::ArcRoute, PeerId};
pub struct PeerMap {
global_ctx: ArcGlobalCtx,
peer_map: DashMap<PeerId, Arc<Peer>>,
packet_send: mpsc::Sender<Bytes>,
}
impl PeerMap {
pub fn new(packet_send: mpsc::Sender<Bytes>) -> Self {
pub fn new(packet_send: mpsc::Sender<Bytes>, global_ctx: ArcGlobalCtx) -> Self {
PeerMap {
global_ctx,
peer_map: DashMap::new(),
packet_send,
}
@@ -29,11 +32,11 @@ impl PeerMap {
self.peer_map.insert(peer.peer_node_id, Arc::new(peer));
}
pub async fn add_new_peer_conn(&self, peer_conn: PeerConn, global_ctx: ArcGlobalCtx) {
pub async fn add_new_peer_conn(&self, peer_conn: PeerConn) {
let peer_id = peer_conn.get_peer_id();
let no_entry = self.peer_map.get(&peer_id).is_none();
if no_entry {
let new_peer = Peer::new(peer_id, self.packet_send.clone(), global_ctx);
let new_peer = Peer::new(peer_id, self.packet_send.clone(), self.global_ctx.clone());
new_peer.add_peer_conn(peer_conn).await;
self.add_new_peer(new_peer).await;
} else {
@@ -51,6 +54,14 @@ impl PeerMap {
msg: Bytes,
dst_peer_id: &uuid::Uuid,
) -> Result<(), Error> {
if *dst_peer_id == self.global_ctx.get_id() {
return Ok(self
.packet_send
.send(msg)
.await
.with_context(|| "send msg to self failed")?);
}
match self.get_peer_by_id(dst_peer_id) {
Some(peer) => {
peer.send_msg(msg).await?;
@@ -70,6 +81,14 @@ impl PeerMap {
dst_peer_id: &uuid::Uuid,
route: ArcRoute,
) -> Result<(), Error> {
if *dst_peer_id == self.global_ctx.get_id() {
return Ok(self
.packet_send
.send(msg)
.await
.with_context(|| "send msg to self failed")?);
}
// get route info
let gateway_peer_id = route.get_next_hop(dst_peer_id).await;
+21 -10
View File
@@ -1,5 +1,6 @@
use std::sync::Arc;
use easytier_rpc::cli::PeerInfo;
use easytier_rpc::peer_manage_rpc_server::PeerManageRpc;
use easytier_rpc::{ListPeerRequest, ListPeerResponse, ListRouteRequest, ListRouteResponse};
use tonic::{Request, Response, Status};
@@ -14,17 +15,10 @@ impl PeerManagerRpcService {
pub fn new(peer_manager: Arc<PeerManager>) -> Self {
PeerManagerRpcService { peer_manager }
}
}
#[tonic::async_trait]
impl PeerManageRpc for PeerManagerRpcService {
async fn list_peer(
&self,
_request: Request<ListPeerRequest>, // Accept request of type HelloRequest
) -> Result<Response<ListPeerResponse>, Status> {
let mut reply = ListPeerResponse::default();
pub async fn list_peers(&self) -> Vec<PeerInfo> {
let peers = self.peer_manager.get_peer_map().list_peers().await;
let mut peer_infos = Vec::new();
for peer in peers {
let mut peer_info = easytier_rpc::PeerInfo::default();
peer_info.peer_id = peer.to_string();
@@ -38,7 +32,24 @@ impl PeerManageRpc for PeerManagerRpcService {
peer_info.conns = conns;
}
reply.peer_infos.push(peer_info);
peer_infos.push(peer_info);
}
peer_infos
}
}
#[tonic::async_trait]
impl PeerManageRpc for PeerManagerRpcService {
async fn list_peer(
&self,
_request: Request<ListPeerRequest>, // Accept request of type HelloRequest
) -> Result<Response<ListPeerResponse>, Status> {
let mut reply = ListPeerResponse::default();
let peers = self.list_peers().await;
for peer in peers {
reply.peer_infos.push(peer);
}
Ok(Response::new(reply))