46 lines
1.8 KiB
Rust
46 lines
1.8 KiB
Rust
//! Asking `brokerd` for a session's state on its `state.sock` (M5c spec, section 7): one question
|
|
//! per connection, one final answer, as on every socket between the roles.
|
|
|
|
use std::os::unix::net::UnixStream;
|
|
use std::path::Path;
|
|
use std::time::Duration;
|
|
|
|
use bxcore::{
|
|
Envelope, Message, PROTOCOL_VERSION, SessionId, SessionState, SessionStateReply, read_frame,
|
|
write_frame,
|
|
};
|
|
|
|
/// How long `brokerd` may leave the connection without a byte, sending or answering.
|
|
pub const WAIT: Duration = Duration::from_secs(5);
|
|
|
|
/// The runbook entry for a `brokerd` that does not answer.
|
|
pub const RUNBOOK: &str = "see docs/runbook.md#broker-state-unavailable";
|
|
|
|
/// `brokerd`'s answer for `session`, asked on `socket`. `wait` is the read and the write timeout;
|
|
/// the connect has none, and fails at once when nothing listens. Any error, an error frame
|
|
/// included, is `Err` with one line that names the socket or `brokerd`.
|
|
pub fn ask(
|
|
socket: &Path,
|
|
session: &SessionId,
|
|
wait: Duration,
|
|
) -> Result<SessionStateReply, String> {
|
|
let line = |e: &dyn std::fmt::Display| format!("{}: {e}", socket.display());
|
|
let mut stream = UnixStream::connect(socket).map_err(|e| line(&e))?;
|
|
stream.set_read_timeout(Some(wait)).map_err(|e| line(&e))?;
|
|
stream.set_write_timeout(Some(wait)).map_err(|e| line(&e))?;
|
|
let question = Envelope {
|
|
v: PROTOCOL_VERSION,
|
|
id: 1,
|
|
r#final: true,
|
|
msg: Message::SessionState(SessionState {
|
|
session: session.clone(),
|
|
}),
|
|
};
|
|
write_frame(&mut stream, &question).map_err(|e| line(&e))?;
|
|
match read_frame(&mut stream).map_err(|e| line(&e))?.msg {
|
|
Message::SessionStateReply(reply) => Ok(reply),
|
|
Message::Error(e) => Err(format!("brokerd: {}", e.detail)),
|
|
_ => Err("brokerd answered with the wrong message".to_string()),
|
|
}
|
|
}
|