use crate::common::ProtocolError;
use crate::core::hub::Hub;
use crate::ConnectionError;
use crate::{core::connection_handler::ConnectionHandler, Router};
use kaspa_utils::networking::NetAddress;
use kaspa_utils_tower::counters::TowerConnectionCounters;
use std::ops::Deref;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc::channel as mpsc_channel;
use tokio::sync::oneshot::Sender as OneshotSender;
use super::peer::PeerKey;
#[tonic::async_trait]
pub trait ConnectionInitializer: Sync + Send {
async fn initialize_connection(&self, new_router: Arc<Router>) -> Result<(), ProtocolError>;
}
pub struct Adaptor {
_server_termination: Option<OneshotSender<()>>,
connection_handler: ConnectionHandler,
hub: Hub,
}
impl Adaptor {
pub(crate) fn new(server_termination: Option<OneshotSender<()>>, connection_handler: ConnectionHandler, hub: Hub) -> Self {
Self { _server_termination: server_termination, connection_handler, hub }
}
pub fn client_only(hub: Hub, initializer: Arc<dyn ConnectionInitializer>, counters: Arc<TowerConnectionCounters>) -> Arc<Self> {
let (hub_sender, hub_receiver) = mpsc_channel(Self::hub_channel_size());
let connection_handler = ConnectionHandler::new(hub_sender, initializer.clone(), counters);
let adaptor = Arc::new(Adaptor::new(None, connection_handler, hub));
adaptor.hub.clone().start_event_loop(hub_receiver, initializer);
adaptor
}
pub fn bidirectional(
serve_address: NetAddress,
hub: Hub,
initializer: Arc<dyn ConnectionInitializer>,
counters: Arc<TowerConnectionCounters>,
) -> Result<Arc<Self>, ConnectionError> {
let (hub_sender, hub_receiver) = mpsc_channel(Self::hub_channel_size());
let connection_handler = ConnectionHandler::new(hub_sender, initializer.clone(), counters);
let server_termination = connection_handler.serve(serve_address)?;
let adaptor = Arc::new(Adaptor::new(Some(server_termination), connection_handler, hub));
adaptor.hub.clone().start_event_loop(hub_receiver, initializer);
Ok(adaptor)
}
pub async fn connect_peer(&self, peer_address: String) -> Result<PeerKey, ConnectionError> {
self.connection_handler.connect_with_retry(peer_address, 1, Default::default()).await.map(|r| r.key())
}
pub async fn connect_peer_with_retries(
&self,
peer_address: String,
retry_attempts: u8,
retry_interval: Duration,
) -> Result<PeerKey, ConnectionError> {
self.connection_handler.connect_with_retry(peer_address, retry_attempts, retry_interval).await.map(|r| r.key())
}
pub async fn close(&self) {
self.terminate_all_peers().await;
}
pub fn hub_channel_size() -> usize {
512
}
}
impl Deref for Adaptor {
type Target = Hub;
fn deref(&self) -> &Self::Target {
&self.hub
}
}