use log::{error, info}; use tokio::net::{ UnixStream, UnixListener }; use tokio::time::{sleep, Duration}; use std::fs; use tokio::io::{ AsyncWriteExt, AsyncReadExt}; use noxis_cli::Cli; /// # Fn `init_cli_pipeline` /// ## for catching all input requests from CLI /// /// *input* : - /// /// *output* : `anyhow::Result<()>` to wrap errors /// /// *initiator* : fn `main` /// /// *managing* : `TcpListener` object to handle requests /// /// *depends on* : - /// pub async fn init_cli_pipeline() -> anyhow::Result<()> { let socket_path = "noxis.sock"; let _ = fs::remove_file(socket_path); match UnixListener::bind(socket_path) { Ok(list) => { // TODO: remove `unwrap`s info!("Listening on {}", socket_path); loop { match list.accept().await { Ok((socket, _)) => { // tokio::spawn(); process_connection(socket).await; }, Err(er) => { error!("Cannot poll connection to CLI due to {}", er); sleep(Duration::from_millis(300)).await; }, } } // Ok(()) }, Err(er) => { error!("Failed to open UnixListener for CLI"); Err(er.into()) }, } } /// # Fn `process_connection` /// ## for processing input CLI requests /// /// *input* : mut stream: `TcpStream` /// /// *output* : - /// /// *initiator* : fn `init_cli_pipeline` /// /// *managing* : mutable object of `TcpStream` /// /// *depends on* : `tokio::net::TcpStream` /// async fn process_connection(mut stream: UnixStream) { let mut buf = vec![0; 1024]; match stream.read(&mut buf).await { Ok(0) => { info!("Client disconnected "); }, Ok(n) => { buf.truncate(n); info!("CLI have sent {} bytes", n); match serde_json::from_slice::(&buf) { Ok(cli) => { info!("Received CLI request: {:?}", cli); let response = "OK"; if let Err(e) = stream.write_all(response.as_bytes()).await { error!("Failed to send response: {}", e); } } Err(e) => { error!("Failed to parse CLI request: {}", e); } } }, Err(e) => error!("Failed to read from socket: {}", e), } let _ = stream.shutdown().await; }