hyperion_framework/containerisation/
hyperion_container_factory.rs1use std::fmt::Debug;
25use std::fs;
26use std::path::PathBuf;
27use std::str::FromStr;
28use std::sync::{Arc as StdArc, atomic::AtomicUsize};
29
30use log::LevelFilter;
32use serde::{Serialize, de::DeserializeOwned};
33use tokio::sync::{Notify, mpsc};
34use tokio::task;
35use tokio::time::{Duration, sleep};
36
37use crate::containerisation::client_broker::ClientBroker;
39use crate::containerisation::hyperion_container::HyperionContainer;
40use crate::containerisation::traits::{
41 ContainerIdentidy, HyperionContainerDirectiveMessage, Initialisable, LogLevel, Run,
42};
43use crate::logging::logging_service::initialise_logger;
44use crate::network::network_topology::NetworkTopology;
45use crate::network::server::Server;
46use crate::utilities::load_config;
47
48pub async fn create<A, C, T>(
52 config_path_str: &str,
53 network_topology_path_str: &str,
54 container_state: StdArc<AtomicUsize>,
55 container_state_notify: StdArc<Notify>,
56 main_rx: mpsc::Receiver<T>,
57) -> HyperionContainer<A, T>
58where
59 A: Initialisable<ConfigType = C> + Run<Message = T> + Send + 'static + Sync + Clone + Debug,
60 C: Debug + Send + 'static + DeserializeOwned + Sync + LogLevel + ContainerIdentidy,
61 T: HyperionContainerDirectiveMessage
62 + Debug
63 + Send
64 + 'static
65 + DeserializeOwned
66 + Sync
67 + Clone
68 + Serialize,
69{
70 let config_path: PathBuf =
72 fs::canonicalize(config_path_str).expect("Could not create path for component config");
73 let component_config: StdArc<C> =
74 load_config::load_config::<C>(config_path).expect("Component config could not be loaded");
75 let network_topology_path = fs::canonicalize(network_topology_path_str)
76 .expect("Could not create path for network config");
77 let network_topology: StdArc<NetworkTopology> =
78 load_config::load_config::<NetworkTopology>(network_topology_path)
79 .expect("Component config could not be loaded");
80
81 initialise_logger(Some(
83 LevelFilter::from_str(component_config.log_level()).unwrap_or(LevelFilter::Info),
84 ))
85 .unwrap();
86
87 for (key, value) in component_config.container_identity().iter() {
89 log::debug!("{key}: {value}");
90 }
91
92 log::info!(
94 "Building Hyperion Container for {}...",
95 component_config
96 .container_identity()
97 .get("name")
98 .unwrap_or(&"Unknown".to_string())
99 );
100
101 let component_archetype = A::initialise(
103 container_state.clone(),
104 container_state_notify.clone(),
105 component_config.clone(),
106 );
107
108 let (server_tx, server_rx) = mpsc::channel::<T>(32);
110 let arc_server: StdArc<Server<T>> = Server::new(
111 network_topology.server_address.clone(),
112 server_tx,
113 container_state.clone(),
114 container_state_notify.clone(),
115 );
116 task::spawn(async move {
117 if let Err(e) = Server::run(arc_server).await {
119 log::error!("Server encountered an error: {e:?}");
120 }
121 });
122
123 sleep(Duration::from_secs(2)).await;
125
126 let client_broker: ClientBroker<T> = ClientBroker::init(
128 network_topology,
129 container_state.clone(),
130 container_state_notify.clone(),
131 );
132
133 sleep(Duration::from_secs(2)).await;
135
136 HyperionContainer::<A, T>::create(
138 component_archetype,
139 container_state,
140 container_state_notify,
141 client_broker,
142 main_rx,
143 server_rx,
144 )
145}