satex_discovery/
lib.rs

1#![allow(dead_code)]
2
3use std::fmt::{Debug, Formatter};
4use std::sync::Arc;
5
6use async_trait::async_trait;
7
8use satex_core::endpoint::Endpoint;
9use satex_core::essential::Essential;
10use satex_core::{export_make, Error};
11
12pub mod lb;
13mod make;
14mod registry;
15mod selector;
16export_make!(MakeServerDiscovery);
17
18#[async_trait]
19pub trait ServerDiscovery {
20    async fn resolve(&self, essential: &Essential, server: &str)
21        -> Result<Option<Endpoint>, Error>;
22}
23
24#[derive(Clone)]
25pub struct NamedServerDiscovery {
26    name: &'static str,
27    inner: Arc<dyn ServerDiscovery + Send + Sync + 'static>,
28}
29
30impl Debug for NamedServerDiscovery {
31    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32        f.debug_struct("ServerDiscovery")
33            .field("name", &self.name)
34            .finish()
35    }
36}
37
38impl NamedServerDiscovery {
39    pub fn new<D: ServerDiscovery + Send + Sync + 'static>(
40        name: &'static str,
41        discovery: D,
42    ) -> Self {
43        Self {
44            name,
45            inner: Arc::new(discovery),
46        }
47    }
48
49    pub fn name(&self) -> &'static str {
50        self.name
51    }
52
53    pub fn composite(discoveries: Vec<NamedServerDiscovery>) -> NamedServerDiscovery {
54        NamedServerDiscovery::new("Composite", CompositeServerDiscovery::new(discoveries))
55    }
56}
57
58#[async_trait]
59impl ServerDiscovery for NamedServerDiscovery {
60    async fn resolve(
61        &self,
62        essential: &Essential,
63        server: &str,
64    ) -> Result<Option<Endpoint>, Error> {
65        self.inner.resolve(essential, server).await
66    }
67}
68
69struct CompositeServerDiscovery {
70    discoveries: Vec<NamedServerDiscovery>,
71}
72
73impl CompositeServerDiscovery {
74    pub fn new(discoveries: Vec<NamedServerDiscovery>) -> Self {
75        Self { discoveries }
76    }
77}
78
79#[async_trait]
80impl ServerDiscovery for CompositeServerDiscovery {
81    async fn resolve(
82        &self,
83        essential: &Essential,
84        server: &str,
85    ) -> Result<Option<Endpoint>, Error> {
86        for discovery in self.discoveries.iter() {
87            match discovery.resolve(essential, server).await {
88                Ok(None) => continue,
89                Ok(Some(endpoint)) => return Ok(Some(endpoint)),
90                Err(e) => return Err(e),
91            }
92        }
93        Ok(None)
94    }
95}