Get dynamic component loading working

This commit is contained in:
Michael Mikovsky
2025-11-14 09:43:41 -07:00
parent cc2b2960e8
commit f34ac017ce
13 changed files with 119 additions and 82 deletions
+8
View File
@@ -1,8 +1,16 @@
use bincode::{Decode, Encode};
use crate::config::RuntimeConfig;
#[derive(Debug, Encode, Decode)]
pub enum Announcement {
TestAnnouncement(String),
GetRuntimes,
GetRuntimesAck(usize),
StartRuntime(RuntimeConfig),
StartRuntimeAck(bool),
}
const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard();
+18 -11
View File
@@ -2,7 +2,7 @@ use std::{
io::Read,
net::TcpStream,
sync::{
Arc,
Arc, Mutex,
atomic::{AtomicBool, Ordering},
},
thread::{self, JoinHandle},
@@ -43,16 +43,6 @@ impl ClientRuntime {
}
};
info!("Connected");
// let reader = BufReader::new(stream.try_clone().unwrap());
// let mut writer = BufWriter::new(stream.try_clone().unwrap());
// let (a, b) = crossbeam_channel::unbounded();
// a.
// if join_receiver.len() == 0 {
// join_receiver.recv().unwrap();
// }
while !join_clone.load(Ordering::Relaxed) {
let mut size_buf = [0u8; 4];
@@ -69,12 +59,29 @@ impl ClientRuntime {
Announcement::TestAnnouncement(s) => {
println!("Received test announcement: {}", s)
}
_ => {}
}
}
}),
join_signal,
})
}
// pub fn send(&mut self, announcement: &Announcement) -> Result<(), ModuleError> {
// let bytes = announcement.encode();
// let mut streams = self.stream.lock().unwrap();
// for stream in streams.iter_mut() {
// stream.write_all(&u32::to_be_bytes(bytes.len() as u32))?;
// stream.write_all(&bytes)?;
// stream.flush()?;
// }
// println!("Announcement {:?} sent", announcement);
// Ok(())
// }
}
impl ModuleRuntime for ClientRuntime {
-12
View File
@@ -4,20 +4,8 @@ use crate::config::NamedComponent;
#[obfuscated_symbol]
pub fn get_components() -> Vec<NamedComponent> {
// let mut components: HashMap<&'static str, Box<dyn Component>> = HashMap::new();
// let a = crate::client::get_interface;
return vec![
#[cfg(feature = "client")]
crate::client::get_named_component(),
];
// components
// vec![
// Feature::Client,
// #[cfg(feature = "server")]
// Feature::Server,
// ]
}
+6 -4
View File
@@ -3,6 +3,8 @@ use std::collections::HashMap;
// use bincode::{Decode, Encode};
// use serde::{Deserialize, Serialize};
use bincode::{Decode, Encode};
use crate::{ModuleError, ModuleRuntime};
// /// Payload config that is instantiated
@@ -19,11 +21,11 @@ pub struct PayloadConfig {
pub runtime_config: Vec<RuntimeConfig>,
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Encode, Decode)]
pub struct RuntimeConfig {
pub parent_component: &'static str,
pub name: &'static str,
pub config: HashMap<&'static str, String>,
pub parent_component: String,
pub name: String,
pub config: HashMap<String, String>,
}
#[derive(Clone)]
+1 -6
View File
@@ -10,15 +10,10 @@ mod components;
pub use components::get_components;
mod announcement;
use std::{
fmt,
// sync::{Arc, Mutex},
};
use std::fmt;
pub use announcement::Announcement;
// use crate::module::{Interface, Manager};
///Generic error type for module-related operations.
#[derive(Debug)]
pub enum ModuleError {
+18 -10
View File
@@ -19,18 +19,17 @@ pub struct Manager {
pub modules: Vec<Module>,
active_runtimes: Vec<Box<dyn ModuleRuntime>>,
// runtime_config: Vec<RuntimeConfig>,
components: HashMap<String, NamedComponent>,
}
// static mut MANAGER_RUNTIME: Option<Arc<Mutex<Manager>>> = None;
impl Manager {
fn new(id: &'static str, config: Vec<NamedComponent>, modules: Vec<Module>) -> Self {
fn new(id: &'static str, components: Vec<NamedComponent>, modules: Vec<Module>) -> Self {
Self {
id,
modules,
components: config
components: components
.into_iter()
.map(|c| (c.name.to_string(), c))
.collect(),
@@ -44,6 +43,9 @@ impl Manager {
// Construct self
let mut this = Self::new(&config.id, config.components.clone(), modules);
debug!("Imported {} base components", this.components.len());
debug!("Imported {} base runtimes", &config.runtime_config.len());
// Load each of the pre-prepared modules
this.load_components();
@@ -60,7 +62,7 @@ impl Manager {
for module in &self.modules {
// Load get_components function from shared object library
let component_func = match module
.get_symbol::<fn() -> Vec<NamedComponent>>(symbol!(b"get_components"))
.get_symbol::<fn() -> Vec<NamedComponent>>(symbol!("get_components").as_bytes())
{
Ok(func) => func,
Err(_) => {
@@ -70,7 +72,7 @@ impl Manager {
};
let components = component_func();
let component_name = "TODO";
let component_name = "TODO"; //TODO: Make this actually load component name
debug!("{} - Retrieved payload metadata", component_name);
@@ -88,11 +90,11 @@ impl Manager {
for runtime in runtimes {
let mut this_lock = this.lock().unwrap();
let component = match this_lock.components.get(runtime.parent_component) {
let component = match this_lock.components.get(&runtime.parent_component) {
Some(component) => component,
None => {
warn!(
"Could not find component {} which is referenced by runtime {}",
"Could not find component '{}' which is referenced by runtime: {}",
runtime.parent_component, runtime.name
);
continue;
@@ -119,12 +121,18 @@ impl Manager {
let mut this_lock = this.lock().unwrap();
if this_lock.active_runtimes.len() <= 0 {
debug!("There are no more runtimes! Exiting...");
break;
}
this_lock
.active_runtimes
.retain(|runtime| runtime.is_running());
this_lock.active_runtimes.retain(|runtime| {
if runtime.is_running() {
true
} else {
debug!("Runtime exited!"); //TODO: Make this better
false
}
});
drop(this_lock);
+19 -1
View File
@@ -1,5 +1,5 @@
use std::{
io::Write,
io::{Read, Write},
net::{TcpListener, TcpStream},
sync::{Arc, Mutex},
thread::{self, JoinHandle},
@@ -52,6 +52,24 @@ impl ListenerRuntime {
Ok(())
}
pub fn recv(&mut self) -> Result<Announcement, ModuleError> {
let stream = &mut self.streams.lock().unwrap()[0];
let mut size_buf = [0u8; 4];
stream.read_exact(&mut size_buf).unwrap();
let size = u32::from_be_bytes(size_buf);
let mut buf = vec![0u8; size as usize];
stream.read_exact(&mut buf).unwrap();
if let Some(announcement) = Announcement::decode(&buf) {
Ok(announcement)
} else {
Err(ModuleError::Error("Failed to decode announcement".into()))
}
}
}
impl ModuleRuntime for ListenerRuntime {