use serde_derive::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub enum WorkloadRestartPolicy {
ExponentialBackoff,
ExitWithWorkloadReturn,
RetryInstantly,
#[default]
RetryPause,
}
#[derive(Clone, Debug)]
pub struct RestartPolicyOptions {
pub policy: WorkloadRestartPolicy,
pub pause: Duration,
pub max_retries: Option<u32>,
pub max_backoff: Option<Duration>,
}
impl Default for RestartPolicyOptions {
fn default() -> Self {
Self {
policy: WorkloadRestartPolicy::default(),
pause: Duration::from_secs(1),
max_retries: None,
max_backoff: None,
}
}
}
impl RestartPolicyOptions {
pub fn new(policy: WorkloadRestartPolicy) -> Self {
Self { policy, ..Self::default() }
}
pub fn can_retry(&self, completed_retries: u32) -> bool {
self.max_retries.is_none_or(|max_retries| completed_retries < max_retries)
}
pub fn pause_for_retry(&self, retry_number: u32) -> Duration {
let pause = match self.policy {
WorkloadRestartPolicy::ExponentialBackoff => {
let multiplier = 2u32.saturating_pow(retry_number.saturating_sub(1).min(10));
self.pause.saturating_mul(multiplier)
}
WorkloadRestartPolicy::RetryPause => self.pause,
WorkloadRestartPolicy::RetryInstantly | WorkloadRestartPolicy::ExitWithWorkloadReturn => Duration::ZERO,
};
match self.max_backoff {
Some(max_backoff) => pause.min(max_backoff),
None => pause,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum MainRetryAction {
UseExitCode(i8),
UseRestartPolicy,
Success,
}