use confique::Config;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::{
config::{
audit::AuditConfig,
ipc_security::IpcSecurityConfig,
policy::{
ChildStrategyOverrideConfig, DynamicSupervisorConfig, FailureWindowConfig, GroupConfig,
GroupDependencyConfig, GroupStrategyConfig, MeltdownConfig, RestartBudgetConfig,
SeverityDefaultConfig, SupervisionPipelineConfig,
},
},
spec::{
child_declaration::ChildDeclaration,
supervisor::{BackpressureConfig, EscalationPolicy, SupervisionStrategy},
},
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config, JsonSchema)]
pub struct SupervisorConfig {
#[config(default = [])]
#[serde(default)]
pub include: Vec<PathBuf>,
#[config(nested)]
pub supervisor: SupervisorRootConfig,
#[config(nested)]
pub policy: PolicyConfig,
#[config(nested)]
pub shutdown: ShutdownConfig,
#[config(nested)]
pub observability: ObservabilityConfig,
#[config(nested)]
#[serde(default)]
pub audit: AuditConfig,
#[config(nested)]
#[serde(default)]
pub backpressure: BackpressureConfig,
#[config(default = [])]
#[serde(default)]
pub groups: Vec<GroupConfig>,
#[config(default = [])]
#[serde(default)]
pub group_strategies: Vec<GroupStrategyConfig>,
#[config(default = [])]
#[serde(default)]
pub group_dependencies: Vec<GroupDependencyConfig>,
#[config(default = [])]
#[serde(default)]
pub child_strategy_overrides: Vec<ChildStrategyOverrideConfig>,
#[config(default = [])]
#[serde(default)]
pub severity_defaults: Vec<SeverityDefaultConfig>,
pub dashboard: Option<DashboardIpcConfig>,
#[config(default = [])]
#[serde(default)]
pub children: Vec<ChildDeclaration>,
}
impl rust_config_tree::ConfigSchema for SupervisorConfig {
fn include_paths(layer: &<Self as Config>::Layer) -> Vec<PathBuf> {
layer.include.clone().unwrap_or_default()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config, JsonSchema)]
pub struct SupervisorRootConfig {
pub strategy: SupervisionStrategy,
#[serde(default)]
pub escalation_policy: Option<EscalationPolicy>,
#[config(nested)]
#[serde(default)]
pub dynamic_supervisor: DynamicSupervisorConfig,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config, JsonSchema)]
pub struct PolicyConfig {
pub child_restart_limit: u32,
pub child_restart_window_ms: u64,
pub supervisor_failure_limit: u32,
pub supervisor_failure_window_ms: u64,
pub initial_backoff_ms: u64,
pub max_backoff_ms: u64,
pub jitter_ratio: f64,
pub heartbeat_interval_ms: u64,
pub stale_after_ms: u64,
#[config(nested)]
#[serde(default)]
pub restart_budget: RestartBudgetConfig,
#[config(nested)]
#[serde(default)]
pub failure_window: FailureWindowConfig,
#[config(nested)]
#[serde(default)]
pub meltdown: MeltdownConfig,
#[config(nested)]
#[serde(default)]
pub supervision_pipeline: SupervisionPipelineConfig,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config, JsonSchema)]
pub struct ShutdownConfig {
pub graceful_timeout_ms: u64,
pub abort_wait_ms: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config, JsonSchema)]
pub struct ObservabilityConfig {
pub event_journal_capacity: usize,
pub metrics_enabled: bool,
pub audit_enabled: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config, JsonSchema)]
pub struct DashboardIpcConfig {
pub enabled: bool,
pub target_id: Option<String>,
pub path: Option<PathBuf>,
pub permissions: Option<String>,
pub bind_mode: Option<DashboardIpcBindMode>,
pub registration: Option<DashboardRegistrationConfig>,
#[serde(default)]
pub security_config: Option<IpcSecurityConfig>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum DashboardIpcBindMode {
CreateNew,
ReplaceStale,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Config, JsonSchema)]
pub struct DashboardRegistrationConfig {
pub enabled: bool,
pub relay_registration_path: Option<PathBuf>,
pub display_name: Option<String>,
pub lease_seconds: Option<u64>,
pub registration_heartbeat_interval_seconds: Option<u64>,
}