Skip to main content

relay_knowledge/net/
mod.rs

1//! Network configuration and policy boundary.
2//!
3//! All network-facing code must enter through this module or its children.
4//! This boundary owns event-driven HTTP client and server construction,
5//! listener/socket setup, proxy and TLS policy, request and shutdown timeouts,
6//! and QoS admission. Higher layers supply routers, payloads, and domain
7//! handlers; they should not open sockets, build HTTP clients, or run protocol
8//! loops outside `net`.
9
10use std::{
11    error::Error,
12    fmt,
13    sync::{Arc, RwLock},
14};
15
16use crate::env::{EnvironmentConfig, NetworkEnvOverrides};
17
18pub mod http;
19pub mod qos;
20
21/// Resolved network policy shared by HTTP clients and servers.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct NetworkConfig {
24    pub http: http::HttpConfig,
25    pub qos: qos::QosPolicy,
26}
27
28impl NetworkConfig {
29    /// Resolves environment overrides into validated network configuration.
30    pub fn from_overrides(overrides: &NetworkEnvOverrides) -> Result<Self, NetworkConfigError> {
31        Ok(Self {
32            http: http::HttpConfig::from_overrides(overrides).map_err(NetworkConfigError::Http)?,
33            qos: qos::QosPolicy::from_overrides(overrides).map_err(NetworkConfigError::Qos)?,
34        })
35    }
36}
37
38/// Refreshable network configuration shared by network adapters.
39#[derive(Debug, Clone)]
40pub struct NetworkRuntime {
41    inner: Arc<RwLock<NetworkConfig>>,
42    qos: qos::QosRuntime,
43}
44
45impl NetworkRuntime {
46    /// Creates a refreshable handle from validated network configuration.
47    pub fn from_config(config: NetworkConfig) -> Self {
48        Self {
49            inner: Arc::new(RwLock::new(config)),
50            qos: qos::QosRuntime::default(),
51        }
52    }
53
54    /// Creates a refreshable handle from environment overrides.
55    pub fn from_overrides(overrides: &NetworkEnvOverrides) -> Result<Self, NetworkConfigError> {
56        NetworkConfig::from_overrides(overrides).map(Self::from_config)
57    }
58
59    /// Returns the latest validated network configuration.
60    pub fn current(&self) -> NetworkConfig {
61        self.inner
62            .read()
63            .unwrap_or_else(|poisoned| poisoned.into_inner())
64            .clone()
65    }
66
67    /// Returns the shared QoS runtime counters for network adapters.
68    pub fn qos_runtime(&self) -> qos::QosRuntime {
69        self.qos.clone()
70    }
71
72    /// Replaces the active network configuration after validating overrides.
73    pub fn refresh_from_overrides(
74        &self,
75        overrides: &NetworkEnvOverrides,
76    ) -> Result<NetworkConfig, NetworkConfigError> {
77        let config = NetworkConfig::from_overrides(overrides)?;
78
79        *self
80            .inner
81            .write()
82            .unwrap_or_else(|poisoned| poisoned.into_inner()) = config.clone();
83
84        Ok(config)
85    }
86
87    /// Replaces the active network configuration from a typed environment snapshot.
88    pub fn refresh_from_environment(
89        &self,
90        environment: &EnvironmentConfig,
91    ) -> Result<NetworkConfig, NetworkConfigError> {
92        self.refresh_from_overrides(&environment.network)
93    }
94}
95
96/// Network configuration error grouped by owning submodule.
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub enum NetworkConfigError {
99    Http(http::HttpConfigError),
100    Qos(qos::QosPolicyError),
101}
102
103impl fmt::Display for NetworkConfigError {
104    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
105        match self {
106            Self::Http(error) => write!(formatter, "invalid HTTP configuration: {error}"),
107            Self::Qos(error) => write!(formatter, "invalid QoS policy: {error}"),
108        }
109    }
110}
111
112impl Error for NetworkConfigError {}
113
114#[cfg(test)]
115#[path = "mod_tests.rs"]
116mod tests;