brokerd: runbook pointers for startup failures, no thread panics, args_os
M3a review findings 3, 5 (the cast), 6, 7 (brokerd), 11. A config, directory or socket failure at start now ends with docs/runbook.md#brokerd-start-failed, and losing a listener with #brokerd-listener-lost; both entries are new. Threads start through thread::Builder, so a refused thread is reported instead of silently killing a listener; an aborted connection no longer stops the daemon. brokerd reads args_os and keeps the config path as a path. The "requester went away" result is recorded at the time it happens. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+31
-20
@@ -1,5 +1,6 @@
|
||||
//! `brokerd`: the broker role. `serve` takes the audit lock, binds both sockets, and serves.
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::process::ExitCode;
|
||||
use std::sync::Arc;
|
||||
@@ -10,10 +11,15 @@ use brokerd::runner::Refusing;
|
||||
use brokerd::serve::{self, ServeError};
|
||||
|
||||
const USAGE: &str = "usage: brokerd serve --config <path> [--accept-break]";
|
||||
/// Where the owner looks when brokerd cannot start: its config, a directory or a socket.
|
||||
const START_FAILED: &str = "see docs/runbook.md#brokerd-start-failed";
|
||||
/// Where the owner looks when brokerd stops serving after it started.
|
||||
const LISTENER_LOST: &str = "see docs/runbook.md#brokerd-listener-lost";
|
||||
|
||||
fn main() -> ExitCode {
|
||||
// The first argument must be `serve`.
|
||||
let mut args = std::env::args().skip(1);
|
||||
// `args_os`: a path need not be UTF-8, and `args` would panic on one that is not.
|
||||
let mut args = std::env::args_os().skip(1);
|
||||
match args.next() {
|
||||
Some(command) if command == "serve" => {}
|
||||
_ => return usage(),
|
||||
@@ -29,7 +35,7 @@ fn main() -> ExitCode {
|
||||
let cfg = match Config::load(&config_path) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
eprintln!("brokerd: {e}");
|
||||
eprintln!("brokerd: {e}\n{START_FAILED}");
|
||||
return ExitCode::from(1);
|
||||
}
|
||||
};
|
||||
@@ -49,10 +55,15 @@ fn main() -> ExitCode {
|
||||
eprintln!("brokerd: {e}");
|
||||
return ExitCode::from(2);
|
||||
}
|
||||
Err(e) => {
|
||||
// The audit errors carry their own entry; the rest are this one.
|
||||
Err(ServeError::Audit(e)) => {
|
||||
eprintln!("brokerd: {e}");
|
||||
return ExitCode::from(1);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("brokerd: {e}\n{START_FAILED}");
|
||||
return ExitCode::from(1);
|
||||
}
|
||||
};
|
||||
|
||||
if started.recovered {
|
||||
@@ -73,7 +84,7 @@ fn main() -> ExitCode {
|
||||
match started.run() {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(e) => {
|
||||
eprintln!("brokerd: {e}");
|
||||
eprintln!("brokerd: stopped serving: {e}\n{LISTENER_LOST}");
|
||||
ExitCode::from(1)
|
||||
}
|
||||
}
|
||||
@@ -86,8 +97,10 @@ fn usage() -> ExitCode {
|
||||
}
|
||||
|
||||
/// The `--config` and `--accept-break` flags after `serve`, or `Err(())` for a bad list.
|
||||
fn parse_serve<I: Iterator<Item = String>>(mut args: I) -> Result<(PathBuf, bool), ()> {
|
||||
let mut config: Option<String> = None;
|
||||
/// Flags are compared as `OsStr`, so one that is not UTF-8 is simply unknown; the path is kept as
|
||||
/// given.
|
||||
fn parse_serve<I: Iterator<Item = OsString>>(mut args: I) -> Result<(PathBuf, bool), ()> {
|
||||
let mut config: Option<OsString> = None;
|
||||
let mut accept_break = false;
|
||||
loop {
|
||||
match args.next() {
|
||||
@@ -97,24 +110,22 @@ fn parse_serve<I: Iterator<Item = String>>(mut args: I) -> Result<(PathBuf, bool
|
||||
None => Err(()),
|
||||
};
|
||||
}
|
||||
Some(arg) => match arg.as_str() {
|
||||
"--config" => match args.next() {
|
||||
Some(path) => {
|
||||
if config.is_some() {
|
||||
return Err(());
|
||||
}
|
||||
config = Some(path);
|
||||
}
|
||||
None => return Err(()),
|
||||
},
|
||||
"--accept-break" => {
|
||||
if accept_break {
|
||||
Some(arg) if arg == "--config" => match args.next() {
|
||||
Some(path) => {
|
||||
if config.is_some() {
|
||||
return Err(());
|
||||
}
|
||||
accept_break = true;
|
||||
config = Some(path);
|
||||
}
|
||||
_ => return Err(()),
|
||||
None => return Err(()),
|
||||
},
|
||||
Some(arg) if arg == "--accept-break" => {
|
||||
if accept_break {
|
||||
return Err(());
|
||||
}
|
||||
accept_break = true;
|
||||
}
|
||||
Some(_) => return Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user