p2panda_net/discovery/
api.rs1use std::sync::Arc;
4
5use ractor::{ActorRef, call};
6use thiserror::Error;
7use tokio::sync::{RwLock, broadcast};
8
9use crate::address_book::AddressBook;
10use crate::discovery::actors::{DiscoveryManagerArgs, ToDiscoveryManager};
11use crate::discovery::events::DiscoveryEvent;
12use crate::discovery::{Builder, DiscoveryMetrics};
13use crate::iroh_endpoint::Endpoint;
14
15#[derive(Clone, Debug)]
23pub struct Discovery {
24 #[allow(unused, reason = "used by supervisor behind feature flag")]
25 pub(super) args: DiscoveryManagerArgs,
26 pub(super) inner: Arc<RwLock<Inner>>,
27}
28
29#[derive(Debug)]
30pub(super) struct Inner {
31 pub(super) actor_ref: Option<ActorRef<ToDiscoveryManager>>,
32}
33
34impl Discovery {
35 pub(crate) fn new(
36 actor_ref: Option<ActorRef<ToDiscoveryManager>>,
37 args: DiscoveryManagerArgs,
38 ) -> Self {
39 Self {
40 args,
41 inner: Arc::new(RwLock::new(Inner { actor_ref })),
42 }
43 }
44
45 pub fn builder(address_book: AddressBook, endpoint: Endpoint) -> Builder {
46 Builder::new(address_book, endpoint)
47 }
48
49 pub async fn events(&self) -> Result<broadcast::Receiver<DiscoveryEvent>, DiscoveryError> {
51 let inner = self.inner.read().await;
52 let result = call!(
53 inner.actor_ref.as_ref().expect("actor spawned in builder"),
54 ToDiscoveryManager::Events
55 )
56 .map_err(Box::new)?;
57 Ok(result)
58 }
59
60 pub async fn metrics(&self) -> Result<DiscoveryMetrics, DiscoveryError> {
62 let inner = self.inner.read().await;
63 let result = call!(
64 inner.actor_ref.as_ref().expect("actor spawned in builder"),
65 ToDiscoveryManager::Metrics
66 )
67 .map_err(Box::new)?;
68 Ok(result)
69 }
70}
71
72impl Drop for Inner {
73 fn drop(&mut self) {
74 if let Some(actor_ref) = self.actor_ref.take() {
75 actor_ref.stop(None);
76 }
77 }
78}
79
80#[derive(Debug, Error)]
81pub enum DiscoveryError {
82 #[error(transparent)]
84 ActorSpawn(#[from] ractor::SpawnErr),
85
86 #[cfg(feature = "supervisor")]
88 #[error(transparent)]
89 ActorLinkedSpawn(#[from] crate::supervisor::SupervisorError),
90
91 #[error(transparent)]
93 ActorRpc(#[from] Box<ractor::RactorErr<ToDiscoveryManager>>),
94}