Files
unshell/core-modules/client/src/client_runtime.rs
T

129 lines
3.5 KiB
Rust
Raw Normal View History

use std::{
net,
sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
},
thread::{self, JoinHandle},
2025-11-25 15:22:14 -07:00
time::Duration,
};
use unshell_lib::{
config::RuntimeConfig,
module::Manager,
network::{Stream, TcpStream},
*,
};
// use unshell_modules::{Manager, ModuleRuntime};
use unshell_lib::ModuleRuntime;
2025-11-13 11:52:01 -07:00
pub struct ClientRuntime {
2025-11-25 17:31:09 -07:00
config: &'static RuntimeConfig,
thread_handle: Option<JoinHandle<()>>,
join_signal: Arc<AtomicBool>,
}
2025-11-13 11:52:01 -07:00
impl ClientRuntime {
pub fn new(config: &'static RuntimeConfig) -> Result<ClientRuntime, ModuleError> {
let join_signal = Arc::new(AtomicBool::new(false));
2025-11-25 15:22:14 -07:00
2025-11-13 11:52:01 -07:00
Ok(Self {
2025-11-25 17:31:09 -07:00
config,
thread_handle: None,
join_signal,
2025-11-13 11:52:01 -07:00
})
}
2025-11-14 09:43:41 -07:00
// 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(())
// }
}
2025-11-13 11:52:01 -07:00
impl ModuleRuntime for ClientRuntime {
fn is_running(&self) -> bool {
2025-11-25 17:31:09 -07:00
self.thread_handle.as_ref().is_none_or(|h| h.is_finished())
}
fn kill(self: Box<Self>) {
2025-11-25 17:31:09 -07:00
if !self.is_running() {
self.join_signal.store(true, Ordering::Relaxed);
2025-11-25 17:31:09 -07:00
if let Some(handle) = self.thread_handle {
let _ = handle.join();
}
}
}
2025-11-25 17:31:09 -07:00
fn init(&mut self, manager: Arc<Mutex<Manager>>) -> Result<(), ModuleError> {
let host = match self.config.config.get("host") {
Some(host) => host,
None => {
return Err(ModuleError::Error(
"Could not find HOST in Client Runtime".into(),
));
}
};
let retry = match self.config.config.get("retry") {
Some(retry) => Duration::from_millis(retry.parse::<u64>().unwrap()),
None => {
return Err(ModuleError::Error(
"Could not find RETRY in Client Runtime".into(),
));
}
};
// let join_clone = self.join_signal.clone();
thread::spawn(move || {
debug!("Connecting to server...");
loop {
let stream = match net::TcpStream::connect(host) {
2025-11-25 17:31:09 -07:00
Ok(stream) => stream,
Err(e) => {
error!("Failed to connect to server: {}", e);
thread::sleep(retry);
continue;
}
};
info!("Connected to {}", host);
thread::sleep(Duration::from_millis(100));
// Duration::from_millis(100);
let stream = TcpStream::new(stream);
2025-11-25 17:31:09 -07:00
let stream_clone = stream.try_clone().unwrap();
manager.lock().unwrap().add_connection(stream_clone);
// while !join_clone.load(Ordering::Relaxed) {
// }
while stream.is_alive() {
thread::sleep(Duration::from_millis(100));
}
debug!("Disconnected from 1234 {}", host);
thread::sleep(retry);
}
});
Ok(())
}
}