camel_api/
circuit_breaker.rs1use std::time::Duration;
2
3use crate::BoxProcessor;
4
5#[derive(Clone)]
19pub struct CircuitBreakerConfig {
20 pub failure_threshold: u32,
22 pub success_threshold: u32,
28 pub open_duration: Duration,
30 pub fallback: Option<BoxProcessor>,
32}
33
34impl std::fmt::Debug for CircuitBreakerConfig {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 f.debug_struct("CircuitBreakerConfig")
37 .field("failure_threshold", &self.failure_threshold)
38 .field("success_threshold", &self.success_threshold)
39 .field("open_duration", &self.open_duration)
40 .field("fallback", &self.fallback.as_ref().map(|_| "<processor>"))
41 .finish()
42 }
43}
44
45impl Default for CircuitBreakerConfig {
46 fn default() -> Self {
47 Self {
48 failure_threshold: 5,
49 success_threshold: 1,
50 open_duration: Duration::from_secs(30),
51 fallback: None,
52 }
53 }
54}
55
56impl CircuitBreakerConfig {
57 pub fn new() -> Self {
58 Self::default()
59 }
60
61 pub fn failure_threshold(mut self, n: u32) -> Self {
62 self.failure_threshold = n;
63 self
64 }
65
66 pub fn open_duration(mut self, duration: Duration) -> Self {
67 self.open_duration = duration;
68 self
69 }
70
71 pub fn fallback(mut self, fallback: BoxProcessor) -> Self {
72 self.fallback = Some(fallback);
73 self
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_default_config() {
83 let config = CircuitBreakerConfig::default();
84 assert_eq!(config.failure_threshold, 5);
85 assert_eq!(config.success_threshold, 1);
86 assert_eq!(config.open_duration, Duration::from_secs(30));
87 assert!(config.fallback.is_none());
88 }
89
90 #[test]
91 fn test_builder_pattern() {
92 let config = CircuitBreakerConfig::new()
93 .failure_threshold(3)
94 .open_duration(Duration::from_millis(500));
95 assert_eq!(config.failure_threshold, 3);
96 assert_eq!(config.success_threshold, 1); assert_eq!(config.open_duration, Duration::from_millis(500));
98 }
99}