Skip to main content

tower_retry_plus/
events.rs

1use std::time::{Duration, Instant};
2use tower_resilience_core::events::ResilienceEvent;
3
4/// Events emitted by the retry middleware.
5#[derive(Debug, Clone)]
6pub enum RetryEvent {
7    /// A retry attempt is about to be made.
8    Retry {
9        pattern_name: String,
10        timestamp: Instant,
11        attempt: usize,
12        delay: Duration,
13    },
14    /// The operation succeeded (either on first try or after retries).
15    Success {
16        pattern_name: String,
17        timestamp: Instant,
18        attempts: usize,
19    },
20    /// The operation failed after exhausting all retry attempts.
21    Error {
22        pattern_name: String,
23        timestamp: Instant,
24        attempts: usize,
25    },
26    /// An error occurred but was not retried (filtered by retry predicate).
27    IgnoredError {
28        pattern_name: String,
29        timestamp: Instant,
30    },
31}
32
33impl ResilienceEvent for RetryEvent {
34    fn event_type(&self) -> &'static str {
35        match self {
36            RetryEvent::Retry { .. } => "Retry",
37            RetryEvent::Success { .. } => "Success",
38            RetryEvent::Error { .. } => "Error",
39            RetryEvent::IgnoredError { .. } => "IgnoredError",
40        }
41    }
42
43    fn timestamp(&self) -> Instant {
44        match self {
45            RetryEvent::Retry { timestamp, .. } => *timestamp,
46            RetryEvent::Success { timestamp, .. } => *timestamp,
47            RetryEvent::Error { timestamp, .. } => *timestamp,
48            RetryEvent::IgnoredError { timestamp, .. } => *timestamp,
49        }
50    }
51
52    fn pattern_name(&self) -> &str {
53        match self {
54            RetryEvent::Retry { pattern_name, .. } => pattern_name,
55            RetryEvent::Success { pattern_name, .. } => pattern_name,
56            RetryEvent::Error { pattern_name, .. } => pattern_name,
57            RetryEvent::IgnoredError { pattern_name, .. } => pattern_name,
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_event_types() {
68        let now = Instant::now();
69        let retry = RetryEvent::Retry {
70            pattern_name: "test".to_string(),
71            timestamp: now,
72            attempt: 1,
73            delay: Duration::from_secs(1),
74        };
75        assert_eq!(retry.event_type(), "Retry");
76
77        let success = RetryEvent::Success {
78            pattern_name: "test".to_string(),
79            timestamp: now,
80            attempts: 2,
81        };
82        assert_eq!(success.event_type(), "Success");
83
84        let error = RetryEvent::Error {
85            pattern_name: "test".to_string(),
86            timestamp: now,
87            attempts: 3,
88        };
89        assert_eq!(error.event_type(), "Error");
90
91        let ignored = RetryEvent::IgnoredError {
92            pattern_name: "test".to_string(),
93            timestamp: now,
94        };
95        assert_eq!(ignored.event_type(), "IgnoredError");
96    }
97}