use std::time::Duration;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ExitAction {
Ignore,
Restart,
Shutdown,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ErrorAction {
Ignore,
Shutdown,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RestartPolicy {
Never { on_error: ErrorAction },
Always { backoff: Duration },
Attempts {
max_restarts: usize,
backoff: Duration,
when_exhausted: ErrorAction,
},
}
impl RestartPolicy {
pub fn attempts(max_restarts: usize, backoff: Duration, when_exhausted: ErrorAction) -> Self {
Self::Attempts {
max_restarts,
backoff,
when_exhausted,
}
}
pub fn never(on_error: ErrorAction) -> Self {
Self::Never { on_error }
}
pub fn always(backoff: Duration) -> Self {
Self::Always { backoff }
}
pub fn max_restarts(&self) -> Option<usize> {
match self {
Self::Never { .. } | Self::Always { .. } => None,
Self::Attempts { max_restarts, .. } => Some(*max_restarts),
}
}
pub fn backoff(&self) -> Option<Duration> {
match self {
Self::Never { .. } => None,
Self::Always { backoff } | Self::Attempts { backoff, .. } => Some(*backoff),
}
}
pub fn on_error(&self) -> Option<ErrorAction> {
match self {
Self::Never { on_error } => Some(*on_error),
Self::Always { .. } => None,
Self::Attempts { when_exhausted, .. } => Some(*when_exhausted),
}
}
pub(crate) fn action(&self, restarts: usize) -> FailureAction {
match self {
Self::Never { on_error } => FailureAction::Terminal(*on_error),
Self::Always { backoff } => FailureAction::Restart { backoff: *backoff },
Self::Attempts {
max_restarts,
backoff,
when_exhausted,
} => {
if restarts < *max_restarts {
FailureAction::Restart { backoff: *backoff }
} else {
FailureAction::Terminal(*when_exhausted)
}
},
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ServicePolicy {
on_completed: ExitAction,
restart: RestartPolicy,
}
impl ServicePolicy {
pub fn new(on_completed: ExitAction, restart: RestartPolicy) -> Self {
Self {
on_completed,
restart,
}
}
pub fn on_completed(&self) -> ExitAction {
self.on_completed
}
pub fn restart(&self) -> &RestartPolicy {
&self.restart
}
}
impl Default for ServicePolicy {
fn default() -> Self {
Self {
on_completed: ExitAction::Ignore,
restart: RestartPolicy::never(ErrorAction::Shutdown),
}
}
}
pub(crate) enum FailureAction {
Restart { backoff: Duration },
Terminal(ErrorAction),
}