use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetryConfig {
pub immediate_retries: u32,
pub delayed_intervals: Vec<Duration>,
pub max_retry_count: u32,
}
impl RetryConfig {
pub fn new(immediate_retries: u32, delayed_intervals: Vec<Duration>) -> Self {
let max_retry_count = immediate_retries + delayed_intervals.len() as u32;
Self {
immediate_retries,
delayed_intervals,
max_retry_count,
}
}
pub fn masstransit_default() -> Self {
Self::new(
1, vec![
Duration::from_secs(60), Duration::from_secs(120), Duration::from_secs(240), Duration::from_secs(480), Duration::from_secs(960), ],
)
}
pub fn get_retry_delay(&self, retry_count: u32) -> Option<Duration> {
if retry_count == 0 {
return Some(Duration::from_secs(0)); }
if retry_count <= self.immediate_retries {
return Some(Duration::from_secs(0)); }
let delayed_index = (retry_count - self.immediate_retries - 1) as usize;
self.delayed_intervals.get(delayed_index).copied()
}
pub fn should_retry(&self, retry_count: u32) -> bool {
retry_count <= self.max_retry_count
}
pub fn get_retry_type(&self, retry_count: u32) -> &'static str {
if retry_count == 0 {
"initial"
} else if retry_count <= self.immediate_retries {
"immediate"
} else {
"delayed"
}
}
}
impl Default for RetryConfig {
fn default() -> Self {
Self::masstransit_default()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageRetryInfo {
pub retry_count: u32,
pub last_exception: Option<String>,
pub first_delivery_time: chrono::DateTime<chrono::Utc>,
pub last_retry_time: Option<chrono::DateTime<chrono::Utc>>,
}
impl MessageRetryInfo {
pub fn new() -> Self {
Self {
retry_count: 0,
last_exception: None,
first_delivery_time: chrono::Utc::now(),
last_retry_time: None,
}
}
pub fn increment_retry(&mut self, error_message: Option<String>) {
self.retry_count += 1;
self.last_exception = error_message;
self.last_retry_time = Some(chrono::Utc::now());
}
}
impl Default for MessageRetryInfo {
fn default() -> Self {
Self::new()
}
}