use crate::network::transport::{NetworkError, PeerState};
use dashmap::DashMap;
use runar_common::logging::Logger;
use runar_macros_common::log_debug;
use std::sync::Arc;
pub struct ConnectionPool {
peers: DashMap<String, Arc<PeerState>>,
logger: Arc<Logger>,
}
impl ConnectionPool {
pub fn new(logger: Arc<Logger>) -> Self {
Self {
peers: DashMap::new(),
logger,
}
}
pub fn get_or_create_peer(
&self,
peer_node_id: String,
address: String,
max_idle_streams: usize,
logger: Arc<Logger>,
) -> Arc<PeerState> {
if let Some(existing) = self.peers.get(&peer_node_id) {
existing.clone()
} else {
let peer_state = Arc::new(PeerState::new(
peer_node_id.clone(),
address,
max_idle_streams,
logger,
));
self.peers.insert(peer_node_id.clone(), peer_state.clone());
peer_state
}
}
pub fn get_peer(&self, peer_node_id: &str) -> Option<Arc<PeerState>> {
self.peers.get(peer_node_id).map(|entry| entry.clone())
}
pub async fn remove_peer(&self, peer_node_id: &str) -> Result<(), NetworkError> {
if let Some((_, peer_state)) = self.peers.remove(peer_node_id) {
let _ = peer_state.take_connection().await;
}
Ok(())
}
pub async fn is_peer_connected(&self, peer_node_id: &str) -> bool {
if let Some(peer_state) = self.get_peer(peer_node_id) {
peer_state.is_connected().await
} else {
false
}
}
pub async fn get_connected_peers(&self) -> Vec<String> {
let mut connected_peers = Vec::new();
for entry in self.peers.iter() {
let peer = entry.value();
if peer.has_connection().await {
connected_peers.push(entry.key().clone());
}
}
log_debug!(
self.logger,
"get_connected_peers -> {}",
connected_peers.len()
);
connected_peers
}
}
impl std::fmt::Debug for ConnectionPool {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConnectionPool").finish()
}
}