Skip to main content

nova_boot/
discovery.rs

1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5pub use crate::error::DiscoveryError;
6
7/// Represents a discovered service instance.
8#[derive(Debug, Clone)]
9pub struct ServiceInstance {
10    pub id: String,
11    pub name: String,
12    pub address: String,
13    pub metadata: HashMap<String, String>,
14    pub status: InstanceStatus,
15    pub last_heartbeat: Option<std::time::Instant>,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub enum InstanceStatus {
20    Healthy,
21    Unhealthy,
22    Starting,
23    Draining,
24}
25
26/// A stream of service instance updates.
27pub struct WatchStream {
28    pub rx: tokio::sync::mpsc::Receiver<Vec<ServiceInstance>>,
29}
30
31#[async_trait]
32pub trait Discovery: Send + Sync + 'static {
33    /// Register a service instance. Returns error if registration fails.
34    async fn register(&self, instance: ServiceInstance) -> Result<(), DiscoveryError>;
35
36    /// Discover all healthy instances of a service.
37    async fn discover(&self, service_name: &str) -> Result<Vec<ServiceInstance>, DiscoveryError>;
38
39    /// Send a heartbeat to keep registration alive.
40    async fn heartbeat(&self, service_name: &str, instance_id: &str) -> Result<(), DiscoveryError>;
41
42    /// Remove a service instance from the registry.
43    async fn deregister(&self, service_name: &str, instance_id: &str)
44    -> Result<(), DiscoveryError>;
45
46    /// Watch for changes to a service's instances. Returns a stream of instance lists.
47    async fn watch(&self, service_name: &str) -> Result<WatchStream, DiscoveryError>;
48}