Fix client-daemon protocol & client output

This commit is contained in:
ppom 2024-10-24 12:00:00 +02:00
commit 40fc6e3380
5 changed files with 40 additions and 38 deletions

View file

@ -9,12 +9,11 @@ use std::{
use bincode::Options;
use futures::{SinkExt, StreamExt};
use regex::Regex;
use tokio::{io::AsyncWriteExt, net::UnixStream};
use tokio::net::UnixStream;
use tokio_util::{
bytes::Bytes,
codec::{Framed, LengthDelimitedCodec},
};
use tracing::info;
use crate::{
concepts::{ClientRequest, ClientStatus, Config, DaemonResponse, Order, Pattern},
@ -46,10 +45,10 @@ async fn send_retrieve(socket: &PathBuf, req: &ClientRequest) -> Result<DaemonRe
transport.next().await.ok_or("empty response from server")
);
let encoded_response = or_quit!("failed to decode response", encoded_response);
or_quit!(
Ok(or_quit!(
"failed to decode response",
bin.deserialize(&encoded_response)
)
bin.deserialize::<DaemonResponse>(&encoded_response)
))
}
async fn print_status(cs: ClientStatus, format: Format) -> Result<(), Box<dyn Error>> {
@ -57,7 +56,7 @@ async fn print_status(cs: ClientStatus, format: Format) -> Result<(), Box<dyn Er
Format::JSON => serde_json::to_string_pretty(&cs)?,
Format::YAML => serde_yaml::to_string(&cs)?,
};
tokio::io::stdout().write_all(encoded.as_bytes()).await?;
println!("{}", encoded);
Ok(())
}
@ -144,7 +143,7 @@ pub fn test_regex(
if let Some(line) = line {
match_closure(line);
} else {
info!("no second argument: reading from stdin");
eprintln!("no second argument: reading from stdin");
for line in BufReader::new(stdin()).lines() {
match line {
Ok(line) => match_closure(line),

View file

@ -1,8 +1,11 @@
use std::collections::{BTreeMap, BTreeSet};
use std::collections::BTreeMap;
use super::Match;
use serde::{ser::SerializeStruct, Deserialize, Serialize};
use serde::{
ser::{SerializeMap, SerializeStruct},
Deserialize, Serialize,
};
// We don't need protocol versionning here because
// client and daemon are the same binary
@ -13,7 +16,7 @@ pub enum Order {
Flush,
}
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ClientRequest {
pub order: Order,
pub stream_filter: Option<String>,
@ -32,12 +35,6 @@ pub enum DaemonResponse {
Err(String),
}
#[derive(Clone, Serialize, Deserialize)]
pub struct InfoRes {
pub matches: BTreeMap<(String, String), BTreeMap<Match, BTreeSet<i64>>>,
pub execs: BTreeMap<(String, String, String), BTreeMap<Match, BTreeSet<i64>>>,
}
pub type ClientStatus = BTreeMap<String, BTreeMap<String, BTreeMap<String, PatternStatus>>>;
#[derive(Debug, Default, Deserialize)]
@ -53,24 +50,23 @@ impl Serialize for PatternStatus {
{
// We only skip serializing emptiness if we're on a human-readable format
// This means we're printing for user, not exchanging it over a socket
let state = if serializer.is_human_readable() {
if serializer.is_human_readable() {
let ser_matches = self.matches != 0;
let ser_actions = !self.actions.is_empty();
let mut state = serializer
.serialize_struct("PatternStatus", ser_matches as usize + ser_actions as usize)?;
let mut state =
serializer.serialize_map(Some(ser_matches as usize + ser_actions as usize))?;
if ser_matches {
state.serialize_field("matches", &self.matches)?;
state.serialize_entry("matches", &self.matches)?;
}
if ser_actions {
state.serialize_field("actions", &self.actions)?;
state.serialize_entry("actions", &self.actions)?;
}
state
state.end()
} else {
let mut state = serializer.serialize_struct("PatternStatus", 2)?;
state.serialize_field("matches", &self.matches)?;
state.serialize_field("actions", &self.actions)?;
state
};
state.end()
state.end()
}
}
}

View file

@ -134,7 +134,7 @@ impl FilterManager {
let pattern_status = acc.entry(match_).or_default();
pattern_status
.actions
.insert(manager.action().to_string(), times);
.insert(manager.action().name().into(), times);
}
acc
});

View file

@ -29,18 +29,19 @@ async fn main() {
let cli = Cli::parse();
let (is_daemon, level) = if let SubCommand::Start {
config: _,
loglevel,
socket: _,
} = cli.command
{
(true, loglevel)
} else {
(false, Level::DEBUG)
};
if is_daemon {
// Set log level
let level = if let SubCommand::Start {
loglevel,
config: _,
socket: _,
} = cli.command
{
loglevel
} else {
Level::DEBUG
};
if let Err(err) = tracing_subscriber::fmt::fmt()
.without_time()
.with_target(false)
@ -83,7 +84,11 @@ async fn main() {
exit(0);
}
Err(err) => {
error!("{err}");
if is_daemon {
error!("{err}");
} else {
eprintln!("ERROR {err}");
}
exit(1);
}
}

View file

@ -123,8 +123,10 @@ async fn simple() {
.await
});
let (daemon_exit, _, _) = tokio::join!(handle, handle2, handle3);
let (daemon_exit, flush1, flush2) = tokio::join!(handle, handle2, handle3);
assert!(daemon_exit.is_ok());
assert!(flush1.is_ok());
assert!(flush2.is_ok());
assert_eq!(
// 24 is encountered for the second time, then