use std::{fmt, sync::Arc};
use async_trait::async_trait;
use super::RpcError;
use crate::{
PeerConnection,
PeerManager,
connectivity::{ConnectivityRequester, ConnectivitySelection},
peer_manager::{NodeId, OrNotFound, Peer},
};
#[async_trait]
pub trait RpcCommsProvider: Send + Sync {
async fn fetch_peer(&self, node_id: &NodeId) -> Result<Peer, RpcError>;
async fn dial_peer(&mut self, node_id: &NodeId) -> Result<PeerConnection, RpcError>;
async fn select_connections(&mut self, selection: ConnectivitySelection) -> Result<Vec<PeerConnection>, RpcError>;
}
#[derive(Clone, Debug)]
pub(crate) struct RpcCommsBackend {
connectivity: ConnectivityRequester,
peer_manager: Arc<PeerManager>,
}
impl RpcCommsBackend {
pub(super) fn new(peer_manager: Arc<PeerManager>, connectivity: ConnectivityRequester) -> Self {
Self {
connectivity,
peer_manager,
}
}
pub fn peer_manager(&self) -> &PeerManager {
&self.peer_manager
}
}
#[async_trait]
impl RpcCommsProvider for RpcCommsBackend {
async fn fetch_peer(&self, node_id: &NodeId) -> Result<Peer, RpcError> {
self.peer_manager
.find_by_node_id(node_id)
.await
.or_not_found(node_id)
.map_err(Into::into)
}
async fn dial_peer(&mut self, node_id: &NodeId) -> Result<PeerConnection, RpcError> {
self.connectivity.dial_peer(node_id.clone()).await.map_err(Into::into)
}
async fn select_connections(&mut self, selection: ConnectivitySelection) -> Result<Vec<PeerConnection>, RpcError> {
self.connectivity
.select_connections(selection)
.await
.map_err(Into::into)
}
}
pub struct RequestContext {
request_id: u32,
#[allow(dead_code)]
backend: Box<dyn RpcCommsProvider>,
node_id: NodeId,
}
impl RequestContext {
pub(super) fn new(request_id: u32, node_id: NodeId, backend: Box<dyn RpcCommsProvider>) -> Self {
Self {
request_id,
backend,
node_id,
}
}
pub fn peer_node_id(&self) -> &NodeId {
&self.node_id
}
pub fn request_id(&self) -> u32 {
self.request_id
}
#[allow(dead_code)]
pub async fn fetch_peer(&self) -> Result<Peer, RpcError> {
self.backend.fetch_peer(&self.node_id).await
}
#[allow(dead_code)]
async fn dial_peer(&mut self, node_id: &NodeId) -> Result<PeerConnection, RpcError> {
self.backend.dial_peer(node_id).await
}
#[allow(dead_code)]
async fn select_connections(&mut self, selection: ConnectivitySelection) -> Result<Vec<PeerConnection>, RpcError> {
self.backend.select_connections(selection).await
}
}
impl fmt::Debug for RequestContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RequestContext")
.field("node_id", &self.node_id)
.field("backend", &"dyn RpcCommsProvider")
.finish()
}
}