1use crate::events::BulkheadEvent;
4use std::time::Duration;
5use tower_resilience_core::events::{EventListeners, FnListener};
6
7#[derive(Clone)]
9pub struct BulkheadConfig {
10 pub(crate) max_concurrent_calls: usize,
12 pub(crate) max_wait_duration: Option<Duration>,
14 pub(crate) name: String,
16 pub(crate) event_listeners: EventListeners<BulkheadEvent>,
18}
19
20impl BulkheadConfig {
21 pub fn builder() -> BulkheadConfigBuilder {
23 BulkheadConfigBuilder::new()
24 }
25}
26
27pub struct BulkheadConfigBuilder {
29 max_concurrent_calls: usize,
30 max_wait_duration: Option<Duration>,
31 name: String,
32 event_listeners: EventListeners<BulkheadEvent>,
33}
34
35impl BulkheadConfigBuilder {
36 pub fn new() -> Self {
38 Self {
39 max_concurrent_calls: 25,
40 max_wait_duration: None,
41 name: "bulkhead".to_string(),
42 event_listeners: EventListeners::new(),
43 }
44 }
45
46 pub fn max_concurrent_calls(mut self, max: usize) -> Self {
50 self.max_concurrent_calls = max;
51 self
52 }
53
54 pub fn max_wait_duration(mut self, duration: Option<Duration>) -> Self {
59 self.max_wait_duration = duration;
60 self
61 }
62
63 pub fn name(mut self, name: impl Into<String>) -> Self {
67 self.name = name.into();
68 self
69 }
70
71 pub fn on_call_permitted<F>(mut self, f: F) -> Self
73 where
74 F: Fn(usize) + Send + Sync + 'static,
75 {
76 self.event_listeners.add(FnListener::new(move |event| {
77 if let BulkheadEvent::CallPermitted {
78 concurrent_calls, ..
79 } = event
80 {
81 f(*concurrent_calls);
82 }
83 }));
84 self
85 }
86
87 pub fn on_call_rejected<F>(mut self, f: F) -> Self
89 where
90 F: Fn(usize) + Send + Sync + 'static,
91 {
92 self.event_listeners.add(FnListener::new(move |event| {
93 if let BulkheadEvent::CallRejected {
94 max_concurrent_calls,
95 ..
96 } = event
97 {
98 f(*max_concurrent_calls);
99 }
100 }));
101 self
102 }
103
104 pub fn on_call_finished<F>(mut self, f: F) -> Self
106 where
107 F: Fn(Duration) + Send + Sync + 'static,
108 {
109 self.event_listeners.add(FnListener::new(move |event| {
110 if let BulkheadEvent::CallFinished { duration, .. } = event {
111 f(*duration);
112 }
113 }));
114 self
115 }
116
117 pub fn on_call_failed<F>(mut self, f: F) -> Self
119 where
120 F: Fn(Duration) + Send + Sync + 'static,
121 {
122 self.event_listeners.add(FnListener::new(move |event| {
123 if let BulkheadEvent::CallFailed { duration, .. } = event {
124 f(*duration);
125 }
126 }));
127 self
128 }
129
130 pub fn build(self) -> crate::layer::BulkheadLayer {
132 let config = BulkheadConfig {
133 max_concurrent_calls: self.max_concurrent_calls,
134 max_wait_duration: self.max_wait_duration,
135 name: self.name,
136 event_listeners: self.event_listeners,
137 };
138 crate::layer::BulkheadLayer::new(config)
139 }
140}
141
142impl Default for BulkheadConfigBuilder {
143 fn default() -> Self {
144 Self::new()
145 }
146}