diff options
Diffstat (limited to 'src/socket.rs')
-rw-r--r-- | src/socket.rs | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/socket.rs b/src/socket.rs new file mode 100644 index 0000000..0503d1f --- /dev/null +++ b/src/socket.rs @@ -0,0 +1,94 @@ +use std::{ + collections::HashMap, + fs, + io::{self, Write}, + os::unix::net::UnixListener, + path::Path, + sync::{Arc, RwLock}, + thread, + time::Duration, +}; + +use crate::{energy::EnergyLog, Pid}; + +pub struct LoggingSocketService { + path: String, + logged_energy: Arc<RwLock<HashMap<Pid, EnergyLog>>>, + update_interval: Duration, +} + +impl LoggingSocketService { + pub fn new( + path: &str, + logged_energy: Arc<RwLock<HashMap<Pid, EnergyLog>>>, + update_interval: Duration, + ) -> Self { + LoggingSocketService { + path: path.to_string(), + logged_energy, + update_interval, + } + } + + fn generate_report(&self) -> String { + loop { + if let Ok(logged_energy) = self.logged_energy.try_read() { + let mut result = logged_energy + .iter() + .map(|(key, value)| { + format!( + "{key}: {}J", + value.energy_of_running_tasks + value.energy_of_exited_tasks + ) + }) + .collect::<Vec<_>>() + .join(", "); + result += "\n"; + break result; + } + thread::sleep(Duration::from_millis(10)); + } + } + + pub fn run(self) { + thread::spawn(move || { + let listener = UnixListener::bind(self.path.clone()).unwrap(); + for stream in listener.incoming() { + let mut socket = stream.unwrap(); + loop { + if socket + .write_all(format!("{}", self.generate_report()).as_bytes()) + .is_err() + { + break; + } + thread::sleep(self.update_interval); + } + //TODO: if we ever want to read too + /*let mut reader = BufReader::new(socket.try_clone().unwrap()); + let mut line = String::new(); + while let Ok(bytes_read) = reader.read_line(&mut line) { + if bytes_read == 0 { + break; + } + socket.write_all(format!("got: {line}").as_bytes()); + println!("got: {line}"); + line.clear(); + }*/ + } + }); + } +} + +pub fn start_logging_socket_service( + path: &str, + logged_energy: Arc<RwLock<HashMap<Pid, EnergyLog>>>, + update_interval: Duration, +) -> io::Result<()> { + if Path::new(path).exists() { + fs::remove_file(path)?; + } + let socket = LoggingSocketService::new(path, logged_energy, update_interval); + socket.run(); + Ok(()) +} |