use std::fmt::{Display, Formatter};
pub type SupervisorResult<T> = Result<T, SupervisorError>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SupervisorError {
InvalidConfiguration(String),
ServiceAlreadyRegistered(String),
ServiceNotFound(String),
DependencyNotFound {
service: String,
dependency: String,
},
DependencyCycle(Vec<String>),
DependencyUnavailable {
service: String,
dependency: String,
},
ServiceFailure {
service: String,
reason: String,
},
ShutdownTimeout(String),
ServiceOrphaned(String),
RestartBudgetExceeded(String),
RestartQueueFull,
RestartExecutorStopped,
StatePoisoned,
}
impl Display for SupervisorError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::InvalidConfiguration(reason) => {
write!(formatter, "invalid supervisor configuration: {reason}")
}
Self::ServiceAlreadyRegistered(service) => {
write!(formatter, "service `{service}` is already registered")
}
Self::ServiceNotFound(service) => {
write!(formatter, "service `{service}` is not registered")
}
Self::DependencyNotFound {
service,
dependency,
} => write!(
formatter,
"service `{service}` requires missing dependency `{dependency}`"
),
Self::DependencyCycle(cycle) => {
write!(
formatter,
"service dependency cycle: {}",
cycle.join(" -> ")
)
}
Self::DependencyUnavailable {
service,
dependency,
} => write!(
formatter,
"service `{service}` dependency `{dependency}` is unavailable"
),
Self::ServiceFailure { service, reason } => {
write!(formatter, "service `{service}` failed: {reason}")
}
Self::ShutdownTimeout(service) => {
write!(
formatter,
"service `{service}` exceeded its shutdown timeout"
)
}
Self::ServiceOrphaned(service) => {
write!(
formatter,
"service `{service}` has an orphaned instance and cannot start"
)
}
Self::RestartBudgetExceeded(service) => {
write!(
formatter,
"service `{service}` exhausted its restart budget"
)
}
Self::RestartQueueFull => formatter.write_str("restart executor queue is full"),
Self::RestartExecutorStopped => formatter.write_str("restart executor is unavailable"),
Self::StatePoisoned => formatter.write_str("supervisor state is poisoned"),
}
}
}
impl std::error::Error for SupervisorError {}