torrust_server_lib/
registar.rs1use std::collections::HashMap;
4use std::sync::Arc;
5
6use derive_more::Constructor;
7use tokio::sync::Mutex;
8use tokio::task::JoinHandle;
9use torrust_net_primitives::service_binding::ServiceBinding;
10
11pub type ServiceHeathCheckResult = Result<String, String>;
13
14#[derive(Debug, Constructor)]
18pub struct ServiceHealthCheckJob {
19 pub service_binding: ServiceBinding,
20 pub info: String,
21 pub service_type: String,
22 pub job: JoinHandle<ServiceHeathCheckResult>,
23}
24
25pub type FnSpawnServiceHeathCheck = fn(&ServiceBinding) -> ServiceHealthCheckJob;
29
30#[derive(Clone, Debug, Constructor)]
34pub struct ServiceRegistration {
35 service_binding: ServiceBinding,
36 check_fn: FnSpawnServiceHeathCheck,
37}
38
39impl ServiceRegistration {
40 #[must_use]
41 pub fn spawn_check(&self) -> ServiceHealthCheckJob {
42 (self.check_fn)(&self.service_binding)
43 }
44}
45
46pub type ServiceRegistrationForm = tokio::sync::oneshot::Sender<ServiceRegistration>;
48
49pub type ServiceRegistry = Arc<Mutex<HashMap<ServiceBinding, ServiceRegistration>>>;
51
52#[derive(Clone, Debug)]
54pub struct Registar {
55 registry: ServiceRegistry,
56}
57
58#[allow(clippy::derivable_impls)]
59impl Default for Registar {
60 fn default() -> Self {
61 Self {
62 registry: ServiceRegistry::default(),
63 }
64 }
65}
66
67impl Registar {
68 pub fn new(register: ServiceRegistry) -> Self {
69 Self { registry: register }
70 }
71
72 #[must_use]
74 pub fn give_form(&self) -> ServiceRegistrationForm {
75 let (tx, rx) = tokio::sync::oneshot::channel::<ServiceRegistration>();
76 let register = self.clone();
77 tokio::spawn(async move {
78 register.insert(rx).await;
79 });
80 tx
81 }
82
83 async fn insert(&self, rx: tokio::sync::oneshot::Receiver<ServiceRegistration>) {
85 tracing::debug!("Waiting for the started service to send registration data ...");
86
87 let service_registration = rx
88 .await
89 .expect("it should receive the service registration from the started service");
90
91 let mut mutex = self.registry.lock().await;
92
93 mutex.insert(service_registration.service_binding.clone(), service_registration);
94 }
95
96 #[must_use]
98 pub fn entries(&self) -> ServiceRegistry {
99 self.registry.clone()
100 }
101}