Skip to main content

rakka_discovery/
lib.rs

1//! rakka-discovery. akka.net: `Akka.Discovery`.
2
3use std::collections::HashMap;
4use std::sync::Arc;
5
6use async_trait::async_trait;
7use parking_lot::RwLock;
8
9#[derive(Debug, Clone)]
10pub struct ResolvedTarget {
11    pub host: String,
12    pub port: Option<u16>,
13}
14
15#[derive(Debug, Clone)]
16pub struct Resolved {
17    pub service_name: String,
18    pub addresses: Vec<ResolvedTarget>,
19}
20
21#[async_trait]
22pub trait ServiceDiscovery: Send + Sync + 'static {
23    async fn lookup(&self, service_name: &str) -> Resolved;
24}
25
26#[derive(Default)]
27pub struct StaticDiscovery {
28    services: RwLock<HashMap<String, Vec<ResolvedTarget>>>,
29}
30
31impl StaticDiscovery {
32    pub fn new() -> Arc<Self> {
33        Arc::new(Self::default())
34    }
35
36    pub fn register(&self, name: impl Into<String>, target: ResolvedTarget) {
37        self.services.write().entry(name.into()).or_default().push(target);
38    }
39}
40
41#[async_trait]
42impl ServiceDiscovery for StaticDiscovery {
43    async fn lookup(&self, service_name: &str) -> Resolved {
44        Resolved {
45            service_name: service_name.into(),
46            addresses: self.services.read().get(service_name).cloned().unwrap_or_default(),
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[tokio::test]
56    async fn static_discovery_resolves() {
57        let d = StaticDiscovery::new();
58        d.register("svc", ResolvedTarget { host: "1.2.3.4".into(), port: Some(8080) });
59        let r = d.lookup("svc").await;
60        assert_eq!(r.addresses.len(), 1);
61    }
62}