chie_shared/config/timeout.rs
1//! Timeout configuration
2
3use serde::{Deserialize, Serialize};
4
5/// Timeout configuration for operations
6///
7/// # Examples
8///
9/// Using the default configuration:
10/// ```
11/// use chie_shared::TimeoutConfig;
12///
13/// let config = TimeoutConfig::default();
14/// assert_eq!(config.default_timeout_ms, 30_000);
15/// assert_eq!(config.connection_timeout_ms, 10_000);
16/// assert!(config.keepalive_enabled());
17/// assert!(config.idle_timeout_enabled());
18/// assert!(config.validate().is_ok());
19/// ```
20///
21/// Using preset configurations for different scenarios:
22/// ```
23/// use chie_shared::TimeoutConfig;
24///
25/// // Fast configuration for low-latency operations
26/// let fast_config = TimeoutConfig::fast();
27/// assert_eq!(fast_config.default_timeout_ms, 5_000);
28/// assert_eq!(fast_config.connection_timeout_ms, 3_000);
29///
30/// // Slow configuration for batch/background operations
31/// let slow_config = TimeoutConfig::slow();
32/// assert_eq!(slow_config.default_timeout_ms, 120_000);
33/// assert_eq!(slow_config.read_timeout_ms, 300_000);
34/// ```
35///
36/// Building a custom configuration:
37/// ```
38/// use chie_shared::TimeoutConfigBuilder;
39///
40/// let config = TimeoutConfigBuilder::new()
41/// .default_timeout_ms(45_000)
42/// .connection_timeout_ms(15_000)
43/// .read_timeout_ms(90_000)
44/// .write_timeout_ms(90_000)
45/// .idle_timeout_ms(0) // Disable idle timeout
46/// .keepalive_interval_ms(30_000)
47/// .build();
48///
49/// assert_eq!(config.default_timeout_ms, 45_000);
50/// assert!(!config.idle_timeout_enabled());
51/// assert!(config.keepalive_enabled());
52/// ```
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct TimeoutConfig {
55 /// Default operation timeout in milliseconds
56 pub default_timeout_ms: u64,
57 /// Connection timeout in milliseconds
58 pub connection_timeout_ms: u64,
59 /// Read timeout in milliseconds
60 pub read_timeout_ms: u64,
61 /// Write timeout in milliseconds
62 pub write_timeout_ms: u64,
63 /// Idle timeout in milliseconds (0 = no timeout)
64 pub idle_timeout_ms: u64,
65 /// Keepalive interval in milliseconds (0 = disabled)
66 pub keepalive_interval_ms: u64,
67}
68
69impl Default for TimeoutConfig {
70 fn default() -> Self {
71 Self {
72 default_timeout_ms: 30_000, // 30 seconds
73 connection_timeout_ms: 10_000, // 10 seconds
74 read_timeout_ms: 60_000, // 60 seconds
75 write_timeout_ms: 60_000, // 60 seconds
76 idle_timeout_ms: 300_000, // 5 minutes
77 keepalive_interval_ms: 60_000, // 1 minute
78 }
79 }
80}
81
82impl TimeoutConfig {
83 /// Create a new configuration for fast operations
84 #[must_use]
85 pub const fn fast() -> Self {
86 Self {
87 default_timeout_ms: 5_000,
88 connection_timeout_ms: 3_000,
89 read_timeout_ms: 10_000,
90 write_timeout_ms: 10_000,
91 idle_timeout_ms: 60_000,
92 keepalive_interval_ms: 30_000,
93 }
94 }
95
96 /// Create a new configuration for slow operations
97 #[must_use]
98 pub const fn slow() -> Self {
99 Self {
100 default_timeout_ms: 120_000,
101 connection_timeout_ms: 30_000,
102 read_timeout_ms: 300_000,
103 write_timeout_ms: 300_000,
104 idle_timeout_ms: 600_000,
105 keepalive_interval_ms: 120_000,
106 }
107 }
108
109 /// Check if keepalive is enabled
110 #[must_use]
111 pub const fn keepalive_enabled(&self) -> bool {
112 self.keepalive_interval_ms > 0
113 }
114
115 /// Check if idle timeout is enabled
116 #[must_use]
117 pub const fn idle_timeout_enabled(&self) -> bool {
118 self.idle_timeout_ms > 0
119 }
120
121 /// Validate the timeout configuration
122 ///
123 /// # Errors
124 ///
125 /// Returns error if configuration is invalid
126 pub fn validate(&self) -> crate::ChieResult<()> {
127 use crate::ChieError;
128
129 if self.default_timeout_ms == 0 {
130 return Err(ChieError::validation(
131 "default_timeout_ms must be greater than 0",
132 ));
133 }
134
135 if self.connection_timeout_ms == 0 {
136 return Err(ChieError::validation(
137 "connection_timeout_ms must be greater than 0",
138 ));
139 }
140
141 if self.read_timeout_ms == 0 {
142 return Err(ChieError::validation(
143 "read_timeout_ms must be greater than 0",
144 ));
145 }
146
147 if self.write_timeout_ms == 0 {
148 return Err(ChieError::validation(
149 "write_timeout_ms must be greater than 0",
150 ));
151 }
152
153 Ok(())
154 }
155}
156
157/// Builder for `TimeoutConfig`
158///
159/// # Examples
160///
161/// Building a configuration for API requests:
162/// ```
163/// use chie_shared::TimeoutConfigBuilder;
164///
165/// let config = TimeoutConfigBuilder::new()
166/// .default_timeout_ms(20_000)
167/// .connection_timeout_ms(5_000)
168/// .read_timeout_ms(30_000)
169/// .write_timeout_ms(30_000)
170/// .keepalive_interval_ms(45_000)
171/// .build();
172///
173/// assert_eq!(config.default_timeout_ms, 20_000);
174/// assert!(config.validate().is_ok());
175/// ```
176#[derive(Debug, Default)]
177pub struct TimeoutConfigBuilder {
178 config: TimeoutConfig,
179}
180
181impl TimeoutConfigBuilder {
182 /// Create a new builder with default values
183 #[must_use]
184 pub fn new() -> Self {
185 Self::default()
186 }
187
188 /// Set default timeout
189 #[must_use]
190 pub const fn default_timeout_ms(mut self, ms: u64) -> Self {
191 self.config.default_timeout_ms = ms;
192 self
193 }
194
195 /// Set connection timeout
196 #[must_use]
197 pub const fn connection_timeout_ms(mut self, ms: u64) -> Self {
198 self.config.connection_timeout_ms = ms;
199 self
200 }
201
202 /// Set read timeout
203 #[must_use]
204 pub const fn read_timeout_ms(mut self, ms: u64) -> Self {
205 self.config.read_timeout_ms = ms;
206 self
207 }
208
209 /// Set write timeout
210 #[must_use]
211 pub const fn write_timeout_ms(mut self, ms: u64) -> Self {
212 self.config.write_timeout_ms = ms;
213 self
214 }
215
216 /// Set idle timeout
217 #[must_use]
218 pub const fn idle_timeout_ms(mut self, ms: u64) -> Self {
219 self.config.idle_timeout_ms = ms;
220 self
221 }
222
223 /// Set keepalive interval
224 #[must_use]
225 pub const fn keepalive_interval_ms(mut self, ms: u64) -> Self {
226 self.config.keepalive_interval_ms = ms;
227 self
228 }
229
230 /// Build the configuration
231 #[must_use]
232 pub const fn build(self) -> TimeoutConfig {
233 self.config
234 }
235}