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::{EnvError, 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    /// Re-reads the current process environment and applies network changes.
96    pub fn refresh_from_process_environment(&self) -> Result<NetworkConfig, NetworkRuntimeError> {
97        let environment =
98            EnvironmentConfig::from_process().map_err(NetworkRuntimeError::Environment)?;
99
100        self.refresh_from_environment(&environment)
101            .map_err(NetworkRuntimeError::Config)
102    }
103}
104
105/// Network configuration error grouped by owning submodule.
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub enum NetworkConfigError {
108    Http(http::HttpConfigError),
109    Qos(qos::QosPolicyError),
110}
111
112impl fmt::Display for NetworkConfigError {
113    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
114        match self {
115            Self::Http(error) => write!(formatter, "invalid HTTP configuration: {error}"),
116            Self::Qos(error) => write!(formatter, "invalid QoS policy: {error}"),
117        }
118    }
119}
120
121impl Error for NetworkConfigError {}
122
123/// Error raised while refreshing network config from live environment state.
124#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum NetworkRuntimeError {
126    Environment(EnvError),
127    Config(NetworkConfigError),
128}
129
130impl fmt::Display for NetworkRuntimeError {
131    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
132        match self {
133            Self::Environment(error) => write!(formatter, "{error}"),
134            Self::Config(error) => write!(formatter, "{error}"),
135        }
136    }
137}
138
139impl Error for NetworkRuntimeError {}
140
141#[cfg(test)]
142#[path = "mod_tests.rs"]
143mod tests;