alopex_chirps_file_transfer/
config.rs

1use crate::options::{CompressionAlgorithm, DEFAULT_CHUNK_SIZE};
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4use std::time::Duration;
5
6const DEFAULT_CONCURRENCY: usize = 4;
7const MAX_CONCURRENCY: usize = 16;
8const DEFAULT_MAX_TRANSFERS: usize = 32;
9const DEFAULT_SESSION_RETENTION_HOURS: u64 = 24;
10const DEFAULT_MAX_SESSIONS: usize = 100;
11
12/// Global configuration for file transfer operations.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct FileTransferConfig {
15    pub default_chunk_size: usize,
16    pub default_concurrency: usize,
17    pub max_concurrency: usize,
18    pub default_compression: CompressionAlgorithm,
19    pub global_bandwidth_limit: Option<u64>,
20    pub max_concurrent_transfers: usize,
21    pub chunk_timeout: Duration,
22    pub manifest_timeout: Duration,
23    pub idle_timeout: Duration,
24    pub retry: RetryConfig,
25    pub base_path: PathBuf,
26    pub temp_dir: Option<PathBuf>,
27    pub session_dir: Option<PathBuf>,
28    pub session_retention: Duration,
29    pub max_sessions: usize,
30}
31
32impl Default for FileTransferConfig {
33    fn default() -> Self {
34        FileTransferConfig {
35            default_chunk_size: DEFAULT_CHUNK_SIZE,
36            default_concurrency: DEFAULT_CONCURRENCY,
37            max_concurrency: MAX_CONCURRENCY,
38            default_compression: CompressionAlgorithm::None,
39            global_bandwidth_limit: None,
40            max_concurrent_transfers: DEFAULT_MAX_TRANSFERS,
41            chunk_timeout: Duration::from_secs(30),
42            manifest_timeout: Duration::from_secs(10),
43            idle_timeout: Duration::from_secs(60),
44            retry: RetryConfig::default(),
45            base_path: PathBuf::from("."),
46            temp_dir: None,
47            session_dir: None,
48            session_retention: Duration::from_secs(DEFAULT_SESSION_RETENTION_HOURS * 60 * 60),
49            max_sessions: DEFAULT_MAX_SESSIONS,
50        }
51    }
52}
53
54impl FileTransferConfig {
55    /// Sets the default chunk size for transfers.
56    ///
57    /// # Panics
58    /// This method does not panic.
59    pub fn with_default_chunk_size(mut self, default_chunk_size: usize) -> Self {
60        self.default_chunk_size = default_chunk_size;
61        self
62    }
63
64    /// Sets the default concurrency used for chunk uploads.
65    ///
66    /// # Panics
67    /// This method does not panic.
68    pub fn with_default_concurrency(mut self, default_concurrency: usize) -> Self {
69        self.default_concurrency = default_concurrency;
70        self
71    }
72
73    /// Sets the maximum allowed concurrency for transfers.
74    ///
75    /// # Panics
76    /// This method does not panic.
77    pub fn with_max_concurrency(mut self, max_concurrency: usize) -> Self {
78        self.max_concurrency = max_concurrency;
79        self
80    }
81
82    /// Sets the default compression algorithm.
83    ///
84    /// # Panics
85    /// This method does not panic.
86    pub fn with_default_compression(mut self, default_compression: CompressionAlgorithm) -> Self {
87        self.default_compression = default_compression;
88        self
89    }
90
91    /// Sets a global bandwidth limit (bytes/sec) across transfers.
92    ///
93    /// # Panics
94    /// This method does not panic.
95    pub fn with_global_bandwidth_limit(mut self, global_bandwidth_limit: Option<u64>) -> Self {
96        self.global_bandwidth_limit = global_bandwidth_limit;
97        self
98    }
99
100    /// Sets the maximum concurrent transfers.
101    ///
102    /// # Panics
103    /// This method does not panic.
104    pub fn with_max_concurrent_transfers(mut self, max_concurrent_transfers: usize) -> Self {
105        self.max_concurrent_transfers = max_concurrent_transfers;
106        self
107    }
108
109    /// Sets the per-chunk acknowledgement timeout.
110    ///
111    /// # Panics
112    /// This method does not panic.
113    pub fn with_chunk_timeout(mut self, chunk_timeout: Duration) -> Self {
114        self.chunk_timeout = chunk_timeout;
115        self
116    }
117
118    /// Sets the timeout for manifest exchange.
119    ///
120    /// # Panics
121    /// This method does not panic.
122    pub fn with_manifest_timeout(mut self, manifest_timeout: Duration) -> Self {
123        self.manifest_timeout = manifest_timeout;
124        self
125    }
126
127    /// Sets the idle timeout for transfer progress.
128    ///
129    /// # Panics
130    /// This method does not panic.
131    pub fn with_idle_timeout(mut self, idle_timeout: Duration) -> Self {
132        self.idle_timeout = idle_timeout;
133        self
134    }
135
136    /// Sets retry configuration used for transfers.
137    ///
138    /// # Panics
139    /// This method does not panic.
140    pub fn with_retry(mut self, retry: RetryConfig) -> Self {
141        self.retry = retry;
142        self
143    }
144
145    /// Sets the base path for file operations.
146    ///
147    /// # Panics
148    /// This method does not panic.
149    pub fn with_base_path(mut self, base_path: PathBuf) -> Self {
150        self.base_path = base_path;
151        self
152    }
153
154    /// Sets the directory for temporary files.
155    ///
156    /// # Panics
157    /// This method does not panic.
158    pub fn with_temp_dir(mut self, temp_dir: Option<PathBuf>) -> Self {
159        self.temp_dir = temp_dir;
160        self
161    }
162
163    /// Sets the directory for persisted sessions.
164    ///
165    /// # Panics
166    /// This method does not panic.
167    pub fn with_session_dir(mut self, session_dir: Option<PathBuf>) -> Self {
168        self.session_dir = session_dir;
169        self
170    }
171
172    /// Sets how long to retain persisted sessions.
173    ///
174    /// # Panics
175    /// This method does not panic.
176    pub fn with_session_retention(mut self, session_retention: Duration) -> Self {
177        self.session_retention = session_retention;
178        self
179    }
180
181    /// Sets the maximum number of persisted sessions to keep.
182    ///
183    /// # Panics
184    /// This method does not panic.
185    pub fn with_max_sessions(mut self, max_sessions: usize) -> Self {
186        self.max_sessions = max_sessions;
187        self
188    }
189}
190
191/// Retry configuration for chunk transmissions.
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct RetryConfig {
194    pub max_retries: u8,
195    pub initial_delay: Duration,
196    pub max_delay: Duration,
197    pub backoff_multiplier: f64,
198}
199
200impl Default for RetryConfig {
201    fn default() -> Self {
202        RetryConfig {
203            max_retries: 3,
204            initial_delay: Duration::from_millis(100),
205            max_delay: Duration::from_secs(10),
206            backoff_multiplier: 2.0,
207        }
208    }
209}
210
211impl RetryConfig {
212    /// Sets the maximum retry count for a chunk.
213    ///
214    /// # Panics
215    /// This method does not panic.
216    pub fn with_max_retries(mut self, max_retries: u8) -> Self {
217        self.max_retries = max_retries;
218        self
219    }
220
221    /// Sets the initial retry backoff delay.
222    ///
223    /// # Panics
224    /// This method does not panic.
225    pub fn with_initial_delay(mut self, initial_delay: Duration) -> Self {
226        self.initial_delay = initial_delay;
227        self
228    }
229
230    /// Sets the maximum retry backoff delay.
231    ///
232    /// # Panics
233    /// This method does not panic.
234    pub fn with_max_delay(mut self, max_delay: Duration) -> Self {
235        self.max_delay = max_delay;
236        self
237    }
238
239    /// Sets the retry backoff multiplier.
240    ///
241    /// # Panics
242    /// This method does not panic.
243    pub fn with_backoff_multiplier(mut self, backoff_multiplier: f64) -> Self {
244        self.backoff_multiplier = backoff_multiplier;
245        self
246    }
247}