summaryrefslogtreecommitdiff
path: root/src/socket.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/socket.rs')
-rw-r--r--src/socket.rs94
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(())
+}