use std::{path::Path, sync::Arc};
use iroh_net::{Endpoint, NodeAddr, NodeId};
use iroh_router::Router;
use crate::{
downloader::Downloader,
net_protocol::Blobs,
provider::{CustomEventSender, EventSender},
rpc::client::blobs,
util::local_pool::LocalPool,
};
#[derive(Debug)]
pub struct Node {
router: iroh_router::Router,
client: blobs::MemClient,
_local_pool: LocalPool,
}
#[derive(Debug)]
pub struct Builder<S> {
store: S,
events: EventSender,
endpoint: Option<iroh_net::endpoint::Builder>,
}
impl<S: crate::store::Store> Builder<S> {
pub fn blobs_events(self, events: impl CustomEventSender) -> Self {
Self {
events: events.into(),
..self
}
}
pub fn endpoint(self, endpoint: iroh_net::endpoint::Builder) -> Self {
Self {
endpoint: Some(endpoint),
..self
}
}
pub async fn build(self) -> anyhow::Result<Node> {
let store = self.store;
let events = self.events;
let endpoint = self
.endpoint
.unwrap_or_else(|| Endpoint::builder().discovery_n0())
.bind()
.await?;
let local_pool = LocalPool::single();
let mut router = Router::builder(endpoint.clone());
let downloader =
Downloader::new(store.clone(), endpoint.clone(), local_pool.handle().clone());
let blobs = Arc::new(Blobs::new_with_events(
store.clone(),
local_pool.handle().clone(),
events,
downloader,
endpoint.clone(),
));
router = router.accept(crate::protocol::ALPN.to_vec(), blobs.clone());
let router = router.spawn().await?;
let client = blobs.client();
Ok(Node {
router,
client,
_local_pool: local_pool,
})
}
}
impl Node {
pub fn memory() -> Builder<crate::store::mem::Store> {
Builder {
store: crate::store::mem::Store::new(),
events: Default::default(),
endpoint: None,
}
}
pub async fn persistent(
path: impl AsRef<Path>,
) -> anyhow::Result<Builder<crate::store::fs::Store>> {
Ok(Builder {
store: crate::store::fs::Store::load(path).await?,
events: Default::default(),
endpoint: None,
})
}
pub fn endpoint(&self) -> &Endpoint {
self.router.endpoint()
}
pub fn node_id(&self) -> NodeId {
self.router.endpoint().node_id()
}
pub async fn node_addr(&self) -> anyhow::Result<NodeAddr> {
self.router.endpoint().node_addr().await
}
pub async fn shutdown(self) -> anyhow::Result<()> {
self.router.shutdown().await
}
pub fn blobs(&self) -> &blobs::MemClient {
&self.client
}
}