use std::time::Duration;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct RetryContext {
attempt: u32,
max_attempts: u32,
max_elapsed: Option<Duration>,
total_elapsed: Duration,
attempt_elapsed: Duration,
attempt_timeout: Option<Duration>,
next_delay: Option<Duration>,
retry_after_hint: Option<Duration>,
attempt_timeout_source: Option<AttemptTimeoutSource>,
unreaped_worker_count: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AttemptTimeoutSource {
Configured,
MaxElapsed,
}
impl RetryContext {
pub fn new(
attempt: u32,
max_attempts: u32,
max_elapsed: Option<Duration>,
total_elapsed: Duration,
attempt_elapsed: Duration,
attempt_timeout: Option<Duration>,
) -> Self {
Self {
attempt,
max_attempts,
max_elapsed,
total_elapsed,
attempt_elapsed,
attempt_timeout,
next_delay: None,
retry_after_hint: None,
attempt_timeout_source: None,
unreaped_worker_count: 0,
}
}
#[inline]
pub fn attempt(&self) -> u32 {
self.attempt
}
#[inline]
pub fn max_attempts(&self) -> u32 {
self.max_attempts
}
#[inline]
pub fn max_retries(&self) -> u32 {
self.max_attempts.saturating_sub(1)
}
#[inline]
pub fn max_elapsed(&self) -> Option<Duration> {
self.max_elapsed
}
#[inline]
pub fn total_elapsed(&self) -> Duration {
self.total_elapsed
}
#[inline]
pub fn attempt_elapsed(&self) -> Duration {
self.attempt_elapsed
}
#[inline]
pub fn attempt_timeout(&self) -> Option<Duration> {
self.attempt_timeout
}
#[inline]
pub fn attempt_timeout_source(&self) -> Option<AttemptTimeoutSource> {
self.attempt_timeout_source
}
#[inline]
pub fn unreaped_worker_count(&self) -> u32 {
self.unreaped_worker_count
}
#[inline]
pub fn next_delay(&self) -> Option<Duration> {
self.next_delay
}
#[inline]
pub fn retry_after_hint(&self) -> Option<Duration> {
self.retry_after_hint
}
#[inline]
pub(crate) fn with_next_delay(mut self, delay: Duration) -> Self {
self.next_delay = Some(delay);
self
}
#[inline]
pub(crate) fn with_retry_after_hint(mut self, hint: Option<Duration>) -> Self {
self.retry_after_hint = hint;
self
}
#[inline]
pub(crate) fn with_attempt_timeout_source(
mut self,
source: Option<AttemptTimeoutSource>,
) -> Self {
if let Some(source) = source {
self.attempt_timeout_source = Some(source);
}
self
}
#[inline]
pub(crate) fn with_unreaped_worker_count(mut self, count: u32) -> Self {
self.unreaped_worker_count = count;
self
}
}