1pub use crate::context::{
2 Context, InfrastructureConfig, MinioConfig, MlflowConfig, PostgresConfig, Receiver, RedisConfig,
3};
4
5#[cfg(feature = "messaging")]
6pub use crate::stream::ReceiverExt;
7
8#[cfg(feature = "messaging")]
9pub use crate::publish::ContextPublishExt;
10
11#[cfg(feature = "messaging")]
12pub use crate::rpc::{Request, Response, RpcExt};
13
14#[cfg(feature = "messaging")]
15pub use crate::rpc_streaming::{
16 StreamError, StreamMessage, StreamPayload, StreamReceiver, StreamSender, StreamingRpcExt,
17};
18
19#[cfg(feature = "messaging")]
20pub use crate::discovery::DiscoveryExt;
21pub use crate::discovery::{NodeMetadata, NodeStatus};
22
23pub use crate::schema::{
24 CompatibilityCheck, CompatibilityMode, MessageSchema, MessageVersionInfo, SchemaEvolution, SchemaField,
25 SchemaRegistryExt, SchemaVersioningExt,
26};
27
28pub use crate::auth::{AuthExt, Permission, Policy, Rule};
29
30pub use crate::secrets::{
31 EnvironmentBackend, RedisBackend, SecretBackend, SecretsConfig, SecretsManager, VaultBackend,
32};
33
34#[cfg(feature = "messaging")]
35pub use crate::health::{
36 HealthMonitor, HealthReport, HealthReporter, HealthReportingExt, NodeHealthInfo, SystemHealth,
37};
38
39#[cfg(feature = "messaging")]
40pub use crate::behavior_interrupt::{
41 BehaviorControl, BehaviorInterruptConfig, BehaviorInterruptTrigger, InterruptMode,
42};
43
44pub use crate::metrics::{Counter, Gauge, Histogram, MetricsRegistry, NodeMetrics};
45
46pub use crate::rate_limit::{MultiKeyRateLimiter, RateLimit, RateLimiter, RateLimiterManager};
47
48pub use crate::circuit_breaker::{CircuitBreaker, CircuitBreakerConfig, CircuitState};
49
50#[cfg(feature = "messaging")]
51pub use crate::dead_letter::{DeadLetterConfig, DeadLetterQueue, FailedMessage};
52
53#[cfg(feature = "schema-validation")]
54pub use crate::schema_validation::{
55 export_project_schema, get_project_schema, load_and_validate_project, validate_config_file,
56 validate_node_config_file, validate_node_config_json, validate_project_config, validate_project_json,
57};
58
59pub use crate::dependency::{create_graph, DependencyGraph, ShutdownPlan, StartupPlan};
60
61#[cfg(feature = "messaging")]
62pub use crate::lifecycle::{
63 get_timestamp_ms, topic_node_lifecycle, topic_node_status, topic_node_trigger, ModeChanged, ModeError, ModeRequest,
64 NodeLifecycleAction, NodeLifecycleEvent, NodeLifecycleStatus, NodeStatusEvent, NodeTriggerEvent,
65 TOPIC_MODE_CHANGED, TOPIC_MODE_ERROR, TOPIC_MODE_REQUEST,
66};
67
68pub use crate::topic_registry::{TopicInfo, TopicRegistry, TopologyStats};
69
70pub use crate::topic_utils::{extract_category, format_elapsed_time, TopicMetadata, Topics};
71
72pub use crate::state::{
73 FilesystemStateManager, MemoryStateManager, StateManager, StateOptions, StateSnapshot, VersionedState,
74};
75
76pub use crate::recovery::{
77 BackoffStrategy, DegradationMode, RecoveryAction, RecoveryAttempt, RecoveryHistory, RecoveryManager,
78 RecoveryPolicy, RecoveryPolicyBuilder, RecoveryStats,
79};
80
81#[cfg(feature = "messaging")]
82pub use crate::tracing_otel::{
83 JaegerExporter, SpanBuilder, SpanData, TraceContext, TraceExporter, TracedMessage, TracingConfig, TracingExt,
84 TracingHandle, ZipkinExporter,
85};
86
87pub use crate::profiling::{
88 measure_latency, ExecutionStats, LatencyStats, MemoryStats, PerformanceMetrics, PerformanceReport, ProfilingExt,
89 ThroughputStats, TimerGuard,
90};
91
92pub use crate::service::Service;
93#[cfg(feature = "messaging")]
94pub use crate::service_manager::ServiceManager;
95
96pub use crate::node::{
97 fmt_node_with_controller, run_node, HealthPriority, HealthReportingConfig, HealthStatusExt, Node, NodeImpl,
98 NodeTag, NodeType, RateConfig,
99};
100
101pub use crate::config::{
102 env_or_default, load_and_validate, load_config, load_config_from_env, substitute_env_vars, Validate,
103};
104
105pub use crate::model::{load_labels, load_model_config, CustomLabelsConfig, ModelConfig, PreprocessingConfig};
106
107pub use crate::builder_setter;
108pub use crate::enum_str_method;
109
110pub use crate::messages::Message;
111
112pub use crate::messages::Timestamped;
113
114pub use crate::types::*;
115
116pub use crate::error::{Mecha10Error, Result};
117
118pub use async_trait::async_trait;
119
120pub use tokio::{
121 self, select,
122 time::{interval, sleep, timeout, Duration, Instant},
123};
124
125pub use tokio::task::JoinHandle;
126
127pub use serde::{Deserialize, Serialize};
128pub use serde_json::{self, json, Value as JsonValue};
129
130pub use schemars::JsonSchema;
131
132pub use tracing::{debug, error, info, instrument, trace, warn, Level};
133
134#[cfg(feature = "macros")]
135pub use mecha10_macros::Node;
136
137#[cfg(feature = "macros")]
138pub use mecha10_macros::Config;
139
140#[cfg(feature = "macros")]
141pub use mecha10_macros::ConfigDefaults;
142
143fn since_epoch() -> std::time::Duration {
146 std::time::SystemTime::now()
147 .duration_since(std::time::UNIX_EPOCH)
148 .expect("Time went backwards")
149}
150
151pub fn now_micros() -> u64 {
153 since_epoch().as_micros() as u64
154}
155
156pub fn now_secs() -> u64 {
158 since_epoch().as_secs()
159}
160
161pub fn interval_at_hz(hz: f32) -> tokio::time::Interval {
196 let duration = std::time::Duration::from_secs_f32(1.0 / hz);
197 tokio::time::interval(duration)
198}
199
200pub fn init_logging() {
219 use tracing_subscriber::EnvFilter;
220
221 let base = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
222 let curated = format!("{base},ort=warn,rtc_dtls=error,rtc_ice=error,rtc::peer_connection::handler=error");
223 let env_filter = EnvFilter::try_new(&curated).unwrap_or_else(|_| {
224 EnvFilter::new("info,ort=warn,rtc_dtls=error,rtc_ice=error,rtc::peer_connection::handler=error")
225 });
226
227 #[cfg(feature = "messaging")]
228 {
229 use tracing_subscriber::prelude::*;
230
231 let _ = tracing_subscriber::registry()
232 .with(env_filter)
233 .with(tracing_subscriber::fmt::layer())
234 .with(crate::log_publisher::RedisLogLayer::new())
235 .try_init();
236 }
237
238 #[cfg(not(feature = "messaging"))]
239 {
240 let _ = tracing_subscriber::fmt().with_env_filter(env_filter).try_init();
241 }
242}
243
244#[macro_export]
245macro_rules! in_node_context {
246 ($ctx:expr, $body:block) => {{
247 let _span = tracing::info_span!("node", node_id = $ctx.node_id()).entered();
248 $body
249 }};
250}
251
252pub use in_node_context;
253
254#[macro_export]
255macro_rules! node_binary_main {
256 ($node_crate:ident) => {
257 #[tokio::main]
258 async fn main() -> anyhow::Result<()> {
259 $crate::prelude::init_logging();
260
261 $node_crate::run().await.map_err(|e| anyhow::anyhow!(e))
262 }
263 };
264}
265
266pub use node_binary_main;
267
268pub fn now_millis() -> u64 {
281 since_epoch().as_millis() as u64
282}
283
284pub fn elapsed_micros(timestamp_micros: u64) -> u64 {
305 now_micros().saturating_sub(timestamp_micros)
306}
307
308pub fn timestamp_as_secs(timestamp_micros: u64) -> f64 {
322 timestamp_micros as f64 / 1_000_000.0
323}
324
325pub fn duration_from_hz(hz: f32) -> Duration {
335 Duration::from_secs_f32(1.0 / hz)
336}
337
338pub fn normalize_angle(angle: f32) -> f32 {
351 use std::f32::consts::PI;
352 let mut normalized = angle;
353 while normalized > PI {
354 normalized -= 2.0 * PI;
355 }
356 while normalized < -PI {
357 normalized += 2.0 * PI;
358 }
359 normalized
360}
361
362pub fn normalize_angle_degrees(angle: f32) -> f32 {
372 let mut normalized = angle;
373 while normalized > 180.0 {
374 normalized -= 360.0;
375 }
376 while normalized < -180.0 {
377 normalized += 360.0;
378 }
379 normalized
380}
381
382pub fn angle_difference(from: f32, to: f32) -> f32 {
394 normalize_angle(to - from)
395}
396
397pub fn degrees_to_radians(degrees: f32) -> f32 {
407 degrees * std::f32::consts::PI / 180.0
408}
409
410pub fn radians_to_degrees(radians: f32) -> f32 {
420 radians * 180.0 / std::f32::consts::PI
421}
422
423pub fn safe_divide(numerator: f32, denominator: f32, default: f32) -> f32 {
434 if denominator.abs() < f32::EPSILON {
435 default
436 } else {
437 numerator / denominator
438 }
439}
440
441pub fn clamp<T: PartialOrd>(value: T, min: T, max: T) -> T {
453 if value < min {
454 min
455 } else if value > max {
456 max
457 } else {
458 value
459 }
460}
461
462pub fn lerp(a: f32, b: f32, t: f32) -> f32 {
478 a + (b - a) * t
479}
480
481pub use std::collections::{HashMap, HashSet};
482
483pub use std::sync::{Arc, Mutex};
484
485pub use std::path::{Path, PathBuf};
486
487pub type Shared<T> = Arc<T>;
488
489pub type SharedMut<T> = Arc<Mutex<T>>;