use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default, deny_unknown_fields)]
pub struct AsyncOperationsConfig {
pub operations: Vec<String>,
pub workers: u32,
pub poll_interval_ms: u64,
pub stuck_threshold_secs: u64,
pub max_attempts: u32,
pub result_ttl_secs: u64,
}
impl Default for AsyncOperationsConfig {
fn default() -> Self {
Self {
operations: Vec::new(),
workers: 2,
poll_interval_ms: 500,
stuck_threshold_secs: 300,
max_attempts: 1,
result_ttl_secs: 86_400,
}
}
}
impl AsyncOperationsConfig {
pub fn validate(&self) -> Result<(), String> {
if self.operations.is_empty() {
return Err("[async_operations] operations must list at least one root operation — \
the allowlist is explicit and fail-closed, so an empty list would make \
the whole surface unreachable while looking configured."
.to_string());
}
if self.workers == 0 {
return Err("[async_operations] workers must be at least 1.".to_string());
}
if self.poll_interval_ms < 50 {
return Err("[async_operations] poll_interval_ms must be at least 50.".to_string());
}
if self.stuck_threshold_secs == 0 {
return Err("[async_operations] stuck_threshold_secs must be at least 1.".to_string());
}
if self.max_attempts == 0 {
return Err("[async_operations] max_attempts must be at least 1.".to_string());
}
Ok(())
}
}