brokerd: recover a torn line in place, real dates only, bounded ttl, EMFILE
From the independent review of task 23. A torn last line followed by an empty later file had its recovery written into the later file, which broke the chain for good; the line is now ended in its own file. The log-name rule takes months 01 to 12 and days 01 to 31 only. [approvals] ttl_ms is limited to a day, the longest loopd waits after a pending frame. Running out of file descriptors or memory pauses the listener instead of stopping brokerd (the errors the previous fix skipped do not occur on Linux). args.rs's doc fixed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,10 +56,15 @@ pub struct Config {
|
||||
pub approvals: Approvals,
|
||||
}
|
||||
|
||||
/// The longest an approval may wait: a day, the longest `loopd` waits after a pending frame.
|
||||
pub const MAX_TTL_MS: u64 = 86_400_000;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ConfigError {
|
||||
Read(PathBuf, std::io::Error),
|
||||
Parse(PathBuf, toml::de::Error),
|
||||
/// The file parses, but a value is outside what brokerd accepts.
|
||||
Invalid(PathBuf, String),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ConfigError {
|
||||
@@ -67,6 +72,7 @@ impl std::fmt::Display for ConfigError {
|
||||
match self {
|
||||
ConfigError::Read(path, err) => write!(f, "{}: {err}", path.display()),
|
||||
ConfigError::Parse(path, err) => write!(f, "{}: {err}", path.display()),
|
||||
ConfigError::Invalid(path, why) => write!(f, "{}: {why}", path.display()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,6 +88,17 @@ impl Config {
|
||||
std::fs::read_to_string(path).map_err(|e| ConfigError::Read(path.to_path_buf(), e))?;
|
||||
let config: Config =
|
||||
toml::from_str(&text).map_err(|e| ConfigError::Parse(path.to_path_buf(), e))?;
|
||||
// `loopd` waits at most a day after a pending frame, so a longer approval would be given up
|
||||
// by the caller while `bxctl approvals` still listed it.
|
||||
if !(1..=MAX_TTL_MS).contains(&config.approvals.ttl_ms) {
|
||||
return Err(ConfigError::Invalid(
|
||||
path.to_path_buf(),
|
||||
format!(
|
||||
"[approvals] ttl_ms is {}; it must be from 1 to {MAX_TTL_MS} (a day)",
|
||||
config.approvals.ttl_ms
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(config)
|
||||
}
|
||||
pub fn broker_socket(&self) -> PathBuf {
|
||||
|
||||
Reference in New Issue
Block a user