pub mod push;
use crate::errors::Result;
use crate::types::{InstanceStatus, SchemaManifest};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceInstance {
pub id: String,
pub service_name: String,
pub address: String,
pub port: u16,
pub status: InstanceStatus,
#[serde(default)]
pub metadata: HashMap<String, String>,
pub registered_at: i64,
pub last_health_check: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiscoveryEvent {
pub event_type: crate::registry::EventType,
pub instance: ServiceInstance,
pub timestamp: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub manifest: Option<SchemaManifest>,
}
pub trait DiscoveryEventHandler: Send + Sync {
fn on_event(&self, event: DiscoveryEvent);
}
impl<F> DiscoveryEventHandler for F
where
F: Fn(DiscoveryEvent) + Send + Sync,
{
fn on_event(&self, event: DiscoveryEvent) {
self(event)
}
}
#[async_trait]
pub trait ServiceDiscovery: Send + Sync {
async fn discover(&self, service_name: &str) -> Result<Vec<ServiceInstance>>;
async fn watch(
&self,
service_name: &str,
handler: Box<dyn DiscoveryEventHandler>,
) -> Result<()>;
async fn register(&self, instance: &ServiceInstance) -> Result<()>;
async fn deregister(&self, instance_id: &str) -> Result<()>;
async fn report_health(&self, instance_id: &str, status: InstanceStatus) -> Result<()>;
async fn close(&self) -> Result<()>;
async fn health(&self) -> Result<()>;
}
#[async_trait]
pub trait ManifestFetcher: Send + Sync {
async fn fetch_manifest(&self, instance: &ServiceInstance) -> Result<SchemaManifest>;
}
pub struct ServiceNodeConfig {
pub service_name: String,
pub service_version: String,
pub instance_id: Option<String>,
pub address: String,
pub gateway_url: Option<String>,
pub health_interval_secs: u64,
pub ttl_secs: u64,
}
impl ServiceNodeConfig {
pub fn new(
service_name: impl Into<String>,
service_version: impl Into<String>,
address: impl Into<String>,
) -> Self {
Self {
service_name: service_name.into(),
service_version: service_version.into(),
instance_id: None,
address: address.into(),
gateway_url: None,
health_interval_secs: 10,
ttl_secs: 30,
}
}
}
pub struct GatewayNodeConfig {
pub enable_push: bool,
pub service_names: Vec<String>,
pub health_poll_interval_secs: u64,
pub heartbeat_timeout_secs: u64,
}
impl GatewayNodeConfig {
pub fn new() -> Self {
Self {
enable_push: false,
service_names: Vec::new(),
health_poll_interval_secs: 15,
heartbeat_timeout_secs: 30,
}
}
}
impl Default for GatewayNodeConfig {
fn default() -> Self {
Self::new()
}
}