1use super::{
2 super::{async_api::RangeReaderHandle as AsyncRangeReaderHandle, sync_api::RangeReaderInner},
3 ClustersConfigParseError, Timeouts,
4};
5use once_cell::sync::OnceCell;
6use serde::{Deserialize, Serialize};
7use std::{
8 collections::HashSet,
9 convert::TryInto,
10 path::{Path, PathBuf},
11 sync::Arc,
12 time::Duration,
13};
14use tap::TapFallible;
15
16#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug, Default)]
18pub struct Config {
19 #[serde(alias = "ak")]
20 access_key: String,
21 #[serde(alias = "sk")]
22 secret_key: String,
23
24 bucket: String,
25
26 #[serde(alias = "io_hosts")]
27 io_urls: Option<Vec<String>>,
28
29 #[serde(alias = "uc_hosts")]
30 uc_urls: Option<Vec<String>>,
31
32 #[serde(alias = "monitor_hosts")]
33 monitor_urls: Option<Vec<String>>,
34
35 sim: Option<bool>,
36 normalize_key: Option<bool>,
37 private: Option<bool>,
38 retry: Option<usize>,
39 dot_interval_s: Option<u64>,
40 max_dot_buffer_size: Option<u64>,
41 punish_time_s: Option<u64>,
42 base_timeout_ms: Option<u64>,
43 dial_timeout_ms: Option<u64>,
44 max_retry_concurrency: Option<u32>,
45
46 #[serde(skip)]
47 extra: Extra,
48}
49
50pub type SingleClusterConfig = Config;
52
53impl Config {
54 pub fn builder(
56 access_key: impl Into<String>,
57 secret_key: impl Into<String>,
58 bucket: impl Into<String>,
59 io_urls: Option<Vec<String>>,
60 ) -> ConfigBuilder {
61 ConfigBuilder::new(access_key, secret_key, bucket, io_urls)
62 }
63
64 pub(super) fn with_key<T>(&self, _key: &str, f: impl FnOnce(&Config) -> T) -> Option<T> {
65 Some(f(self))
66 }
67
68 pub(super) fn parse(path: &Path, bytes: &[u8]) -> Result<Self, ClustersConfigParseError> {
69 match path.extension().and_then(|s| s.to_str()) {
70 Some("toml") => toml::from_slice(bytes).map_err(|err| err.into()),
71 Some("json") => serde_json::from_slice(bytes).map_err(|err| err.into()),
72 _ => panic!("QINIU env can only support to be given .toml or .json file"),
73 }
74 .tap_ok_mut(|config: &mut Self| {
75 config.extra.original_path = Some(path.to_owned());
76 })
77 }
78
79 #[inline]
81 pub fn access_key(&self) -> &str {
82 &self.access_key
83 }
84
85 #[inline]
87 pub fn set_access_key(&mut self, access_key: impl Into<String>) -> &mut Self {
88 self.access_key = access_key.into();
89 self.uninit_range_reader_inner();
90 self
91 }
92
93 #[inline]
95 pub fn secret_key(&self) -> &str {
96 &self.secret_key
97 }
98
99 #[inline]
101 pub fn set_secret_key(&mut self, secret_key: impl Into<String>) -> &mut Self {
102 self.secret_key = secret_key.into();
103 self.uninit_range_reader_inner();
104 self
105 }
106
107 #[inline]
109 pub fn bucket(&self) -> &str {
110 &self.bucket
111 }
112
113 #[inline]
115 pub fn set_bucket(&mut self, bucket: impl Into<String>) -> &mut Self {
116 self.bucket = bucket.into();
117 self.uninit_range_reader_inner();
118 self
119 }
120
121 #[inline]
123 pub fn io_urls(&self) -> Option<&[String]> {
124 self.io_urls.as_ref().map(|urls| urls.as_ref())
125 }
126
127 #[inline]
129 pub fn set_io_urls(&mut self, io_urls: Option<impl Into<Vec<String>>>) -> &mut Self {
130 self.io_urls = io_urls.map(|urls| urls.into());
131 self.uninit_range_reader_inner();
132 self
133 }
134
135 #[inline]
137 pub fn uc_urls(&self) -> Option<&[String]> {
138 self.uc_urls.as_ref().map(|urls| urls.as_ref())
139 }
140
141 #[inline]
143 pub fn set_uc_urls(&mut self, uc_urls: Option<impl Into<Vec<String>>>) -> &mut Self {
144 self.uc_urls = uc_urls.map(|urls| urls.into());
145 self.uninit_range_reader_inner();
146 self
147 }
148
149 #[inline]
151 pub fn monitor_urls(&self) -> Option<&[String]> {
152 self.monitor_urls.as_ref().map(|urls| urls.as_ref())
153 }
154
155 #[inline]
157 pub fn set_monitor_urls(&mut self, monitor_urls: Option<impl Into<Vec<String>>>) -> &mut Self {
158 self.monitor_urls = monitor_urls.map(|urls| urls.into());
159 self.uninit_range_reader_inner();
160 self
161 }
162
163 #[inline]
165 pub fn use_getfile_api(&self) -> Option<bool> {
166 self.sim.map(|b| !b)
167 }
168
169 #[inline]
171 pub fn set_use_getfile_api(&mut self, use_getfile_api: Option<bool>) -> &mut Self {
172 self.sim = use_getfile_api.map(|b| !b);
173 self.uninit_range_reader_inner();
174 self
175 }
176
177 #[inline]
179 pub fn normalize_key(&self) -> Option<bool> {
180 self.normalize_key
181 }
182
183 #[inline]
185 pub fn set_normalize_key(&mut self, normalize_key: Option<bool>) -> &mut Self {
186 self.normalize_key = normalize_key;
187 self.uninit_range_reader_inner();
188 self
189 }
190
191 #[inline]
193 pub fn private(&self) -> Option<bool> {
194 self.private
195 }
196
197 #[inline]
199 pub fn set_private(&mut self, private: Option<bool>) -> &mut Self {
200 self.private = private;
201 self.uninit_range_reader_inner();
202 self
203 }
204
205 #[inline]
207 pub fn retry(&self) -> Option<usize> {
208 self.retry
209 }
210
211 #[inline]
213 pub fn set_retry(&mut self, retry: Option<usize>) -> &mut Self {
214 self.retry = retry;
215 self.uninit_range_reader_inner();
216 self
217 }
218
219 #[inline]
221 pub fn dot_interval(&self) -> Option<Duration> {
222 self.dot_interval_s.map(Duration::from_secs)
223 }
224
225 #[inline]
227 pub fn set_dot_interval(&mut self, dot_interval: Option<Duration>) -> &mut Self {
228 self.dot_interval_s = dot_interval.map(|d| d.as_secs());
229 self.uninit_range_reader_inner();
230 self
231 }
232
233 #[inline]
235 pub fn max_dot_buffer_size(&self) -> Option<u64> {
236 self.max_dot_buffer_size
237 }
238
239 #[inline]
241 pub fn set_max_dot_buffer_size(&mut self, max_dot_buffer_size: Option<u64>) -> &mut Self {
242 self.max_dot_buffer_size = max_dot_buffer_size;
243 self.uninit_range_reader_inner();
244 self
245 }
246
247 #[inline]
249 pub fn punish_time(&self) -> Option<Duration> {
250 self.punish_time_s.map(Duration::from_secs)
251 }
252
253 #[inline]
255 pub fn set_punish_time(&mut self, punish_time: Option<Duration>) -> &mut Self {
256 self.punish_time_s = punish_time.map(|d| d.as_secs());
257 self.uninit_range_reader_inner();
258 self
259 }
260
261 #[inline]
263 pub fn base_timeout(&self) -> Option<Duration> {
264 self.base_timeout_ms.map(Duration::from_millis)
265 }
266
267 #[inline]
269 pub fn set_base_timeout(&mut self, base_timeout: Option<Duration>) -> &mut Self {
270 self.base_timeout_ms = base_timeout.map(|d| d.as_millis().try_into().unwrap_or(u64::MAX));
271 self.uninit_range_reader_inner();
272 self
273 }
274
275 #[inline]
277 pub fn connect_timeout(&self) -> Option<Duration> {
278 self.dial_timeout_ms.map(Duration::from_millis)
279 }
280
281 #[inline]
283 pub fn set_connect_timeout(&mut self, connect_timeout: Option<Duration>) -> &mut Self {
284 self.dial_timeout_ms =
285 connect_timeout.map(|d| d.as_millis().try_into().unwrap_or(u64::MAX));
286 self.uninit_range_reader_inner();
287 self
288 }
289
290 #[inline]
292 pub fn max_retry_concurrency(&self) -> Option<u32> {
293 self.max_retry_concurrency
294 }
295
296 #[inline]
298 pub fn set_max_retry_concurrency(&mut self, max_retry_concurrency: Option<u32>) -> &mut Self {
299 self.max_retry_concurrency = max_retry_concurrency;
300 self.uninit_range_reader_inner();
301 self
302 }
303
304 pub(super) fn original_path(&self) -> Option<&Path> {
305 self.extra.original_path.as_ref().map(|p| p.as_ref())
306 }
307
308 #[allow(dead_code)]
309 pub(super) fn original_path_mut(&mut self) -> &mut Option<PathBuf> {
310 &mut self.extra.original_path
311 }
312
313 pub(super) fn config_paths(&self) -> Vec<PathBuf> {
314 self.extra
315 .original_path
316 .as_ref()
317 .map(|path| vec![path.to_owned()])
318 .unwrap_or_default()
319 }
320
321 pub(super) fn timeouts_set(&self) -> HashSet<Timeouts> {
322 let mut set = HashSet::with_capacity(1);
323 set.insert(Timeouts::from(self));
324 set
325 }
326
327 pub(crate) fn get_or_init_range_reader_inner(
328 &self,
329 f: impl FnOnce() -> Arc<RangeReaderInner>,
330 ) -> Arc<RangeReaderInner> {
331 self.extra.range_reader_inner.get_or_init(f).to_owned()
332 }
333
334 pub(crate) fn get_or_init_async_range_reader_inner(
335 &self,
336 f: impl FnOnce() -> AsyncRangeReaderHandle,
337 ) -> AsyncRangeReaderHandle {
338 self.extra
339 .async_range_reader_inner
340 .get_or_init(f)
341 .to_owned()
342 }
343
344 fn uninit_range_reader_inner(&mut self) {
345 self.extra.range_reader_inner.take();
346 self.extra.async_range_reader_inner.take();
347 }
348}
349
350#[derive(Debug)]
352pub struct ConfigBuilder(Config);
353
354pub type SingleClusterConfigBuilder = ConfigBuilder;
356
357impl ConfigBuilder {
358 pub fn new(
360 access_key: impl Into<String>,
361 secret_key: impl Into<String>,
362 bucket: impl Into<String>,
363 io_urls: Option<Vec<String>>,
364 ) -> Self {
365 Self(Config {
366 access_key: access_key.into(),
367 secret_key: secret_key.into(),
368 bucket: bucket.into(),
369 io_urls,
370 ..Default::default()
371 })
372 }
373
374 #[inline]
376 pub fn build(self) -> Config {
377 self.0
378 }
379
380 #[inline]
382 pub fn access_key(mut self, access_key: impl Into<String>) -> Self {
383 self.0.access_key = access_key.into();
384 self
385 }
386
387 #[inline]
389 pub fn secret_key(mut self, secret_key: impl Into<String>) -> Self {
390 self.0.secret_key = secret_key.into();
391 self
392 }
393
394 #[inline]
396 pub fn bucket(mut self, bucket: impl Into<String>) -> Self {
397 self.0.bucket = bucket.into();
398 self
399 }
400
401 #[inline]
403 pub fn io_urls(mut self, io_urls: Option<Vec<String>>) -> Self {
404 self.0.io_urls = io_urls;
405 self
406 }
407
408 #[inline]
410 pub fn uc_urls(mut self, uc_urls: Option<Vec<String>>) -> Self {
411 self.0.uc_urls = uc_urls;
412 self
413 }
414
415 #[inline]
417 pub fn monitor_urls(mut self, monitor_urls: Option<Vec<String>>) -> Self {
418 self.0.monitor_urls = monitor_urls;
419 self
420 }
421
422 #[inline]
424 pub fn use_getfile_api(mut self, use_getfile_api: Option<bool>) -> Self {
425 self.0.sim = use_getfile_api.map(|b| !b);
426 self
427 }
428
429 #[inline]
431 pub fn normalize_key(mut self, normalize_key: Option<bool>) -> Self {
432 self.0.normalize_key = normalize_key;
433 self
434 }
435
436 #[inline]
438 pub fn private(mut self, private: Option<bool>) -> Self {
439 self.0.private = private;
440 self
441 }
442
443 #[inline]
445 pub fn retry(mut self, retry: Option<usize>) -> Self {
446 self.0.retry = retry;
447 self
448 }
449
450 #[inline]
452 pub fn punish_duration(mut self, punish_duration: Option<Duration>) -> Self {
453 self.0.punish_time_s = punish_duration.map(|d| d.as_secs());
454 self
455 }
456
457 #[inline]
459 pub fn base_timeout(mut self, base_timeout: Option<Duration>) -> Self {
460 self.0.base_timeout_ms = base_timeout.map(|d| d.as_millis().try_into().unwrap_or(u64::MAX));
461 self
462 }
463
464 #[inline]
466 pub fn connect_timeout(mut self, connect_timeout: Option<Duration>) -> Self {
467 self.0.dial_timeout_ms =
468 connect_timeout.map(|d| d.as_millis().try_into().unwrap_or(u64::MAX));
469 self
470 }
471
472 #[inline]
474 pub fn max_retry_concurrency(mut self, max_retry_concurrency: Option<u32>) -> Self {
475 self.0.max_retry_concurrency = max_retry_concurrency;
476 self
477 }
478
479 #[inline]
481 pub fn dot_interval(mut self, dot_interval: Option<Duration>) -> Self {
482 self.0.dot_interval_s = dot_interval.map(|d| d.as_secs());
483 self
484 }
485
486 #[inline]
488 pub fn max_dot_buffer_size(mut self, max_dot_buffer_size: Option<u64>) -> Self {
489 self.0.max_dot_buffer_size = max_dot_buffer_size;
490 self
491 }
492
493 #[inline]
494 #[cfg(test)]
495 pub(super) fn original_path(mut self, original_path: Option<PathBuf>) -> Self {
496 self.0.extra.original_path = original_path;
497 self
498 }
499}
500
501impl From<Config> for ConfigBuilder {
502 #[inline]
503 fn from(config: Config) -> Self {
504 ConfigBuilder(config)
505 }
506}
507
508#[derive(Default, Clone, Debug)]
509struct Extra {
510 original_path: Option<PathBuf>,
511 range_reader_inner: OnceCell<Arc<RangeReaderInner>>,
512 async_range_reader_inner: OnceCell<AsyncRangeReaderHandle>,
513}
514
515impl PartialEq for Extra {
516 #[inline]
517 fn eq(&self, _: &Self) -> bool {
518 true
519 }
520}
521
522impl Eq for Extra {}