Files
jmb-bar/src/backend/commands.rs

70 lines
2.3 KiB
Rust

use crate::LOGGER;
use crate::backend::{BackendThread, SimpleBackendThread};
use crossbeam_channel::{Receiver, Sender};
use jmb_bar::{ControlCommand, SOCKET_PATH};
use jmb_logger_rs::*;
use std::io::Read;
use std::net::Shutdown;
use std::os::unix::net::UnixListener;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
pub struct ControlSocket {
subscribers: Vec<Sender<ControlCommand>>,
}
impl ControlSocket {
pub fn new() -> Self {
Self {
subscribers: vec![],
}
}
}
impl SimpleBackendThread<ControlCommand> for ControlSocket {
fn subscribers(&self) -> &Vec<Sender<ControlCommand>> {
&self.subscribers
}
fn init(self, registration_rx: Receiver<Sender<ControlCommand>>) {
let instance = Arc::new(Mutex::new(self));
let instance_clone = instance.clone();
std::thread::spawn(move || {
while let Ok(sender) = registration_rx.recv() {
instance_clone.lock().unwrap().subscribers.push(sender);
}
});
std::thread::spawn(move || {
if std::fs::metadata(SOCKET_PATH).is_ok()
&& let Err(e) = std::fs::remove_file(SOCKET_PATH)
{
error!(&LOGGER, "Error deleting old socket file: {e}");
return;
}
let socket = UnixListener::bind(SOCKET_PATH);
let Ok(socket) = socket else {
error!(&LOGGER, "Error creating socket {}", socket.err().unwrap());
return;
};
info!(&LOGGER, "Successfully started control socket");
loop {
if let Ok((mut stream, _addr)) = socket.accept() {
info!(&LOGGER, "Socket accepted connection");
let mut read = String::new();
let res = stream.read_to_string(&mut read);
if let Err(e) = res {
error!(&LOGGER, "Error reading: {e}");
let _ = stream.shutdown(Shutdown::Both);
continue;
}
if let Ok(command) = ControlCommand::from_str(&read) {
instance.lock().unwrap().publish(command);
}
}
}
});
}
}