qiniu_download/config/
single_cluster.rs

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/// 单集群七牛配置信息
17#[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
50/// 单集群七牛配置信息
51pub type SingleClusterConfig = Config;
52
53impl Config {
54    /// 创建七牛配置信息构建器
55    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    /// 获取七牛 Access Key
80    #[inline]
81    pub fn access_key(&self) -> &str {
82        &self.access_key
83    }
84
85    /// 设置七牛 Access Key
86    #[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    /// 获取七牛 Secret Key
94    #[inline]
95    pub fn secret_key(&self) -> &str {
96        &self.secret_key
97    }
98
99    /// 设置七牛 Secret Key
100    #[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    /// 获取七牛存储空间
108    #[inline]
109    pub fn bucket(&self) -> &str {
110        &self.bucket
111    }
112
113    /// 设置七牛存储空间
114    #[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    /// 获取 IO 服务器 URL 列表
122    #[inline]
123    pub fn io_urls(&self) -> Option<&[String]> {
124        self.io_urls.as_ref().map(|urls| urls.as_ref())
125    }
126
127    /// 设置 IO 服务器 URL 列表
128    #[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    /// 获取 UC 服务器 URL 列表
136    #[inline]
137    pub fn uc_urls(&self) -> Option<&[String]> {
138        self.uc_urls.as_ref().map(|urls| urls.as_ref())
139    }
140
141    /// 设置 UC 服务器 URL 列表
142    #[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    /// 获取监控服务器服务器 URL 列表
150    #[inline]
151    pub fn monitor_urls(&self) -> Option<&[String]> {
152        self.monitor_urls.as_ref().map(|urls| urls.as_ref())
153    }
154
155    /// 设置监控服务器 URL 列表
156    #[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    /// 是否使用 Getfile API
164    #[inline]
165    pub fn use_getfile_api(&self) -> Option<bool> {
166        self.sim.map(|b| !b)
167    }
168
169    /// 设置是否使用 Getfile API
170    #[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    /// 是否对 key 进行格式化
178    #[inline]
179    pub fn normalize_key(&self) -> Option<bool> {
180        self.normalize_key
181    }
182
183    /// 设置是否对 key 进行格式化
184    #[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    /// 是否使用私有存储空间
192    #[inline]
193    pub fn private(&self) -> Option<bool> {
194        self.private
195    }
196
197    /// 设置是否使用私有存储空间
198    #[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    /// 获取 IO 和 UC 服务器访问重试次数
206    #[inline]
207    pub fn retry(&self) -> Option<usize> {
208        self.retry
209    }
210
211    /// 设置 IO 和 UC 服务器访问重试次数
212    #[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    /// 获取打点记录上传频率
220    #[inline]
221    pub fn dot_interval(&self) -> Option<Duration> {
222        self.dot_interval_s.map(Duration::from_secs)
223    }
224
225    /// 设置打点记录上传频率
226    #[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    /// 获取打点记录本地缓存文件尺寸上限
234    #[inline]
235    pub fn max_dot_buffer_size(&self) -> Option<u64> {
236        self.max_dot_buffer_size
237    }
238
239    /// 设置打点记录本地缓存文件尺寸上限
240    #[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    /// 获取域名访问失败后的惩罚时长
248    #[inline]
249    pub fn punish_time(&self) -> Option<Duration> {
250        self.punish_time_s.map(Duration::from_secs)
251    }
252
253    /// 设置域名访问失败后的惩罚时长
254    #[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    /// 获取域名访问的基础超时时长
262    #[inline]
263    pub fn base_timeout(&self) -> Option<Duration> {
264        self.base_timeout_ms.map(Duration::from_millis)
265    }
266
267    /// 设置域名访问失败后的惩罚时长
268    #[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    /// 获取域名连接的超时时长
276    #[inline]
277    pub fn connect_timeout(&self) -> Option<Duration> {
278        self.dial_timeout_ms.map(Duration::from_millis)
279    }
280
281    /// 设置域名连接的超时时长
282    #[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    /// 获取最大并行重试次数
291    #[inline]
292    pub fn max_retry_concurrency(&self) -> Option<u32> {
293        self.max_retry_concurrency
294    }
295
296    /// 设置最大并行重试次数,如果设置为 Some(0) 则表示禁止并行重试功能
297    #[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/// 七牛单集群配置信息构建器
351#[derive(Debug)]
352pub struct ConfigBuilder(Config);
353
354/// 七牛单集群配置信息构建器
355pub type SingleClusterConfigBuilder = ConfigBuilder;
356
357impl ConfigBuilder {
358    /// 创建七牛配置信息构建器
359    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    /// 构建七牛配置信息
375    #[inline]
376    pub fn build(self) -> Config {
377        self.0
378    }
379
380    /// 配置七牛 Access Key
381    #[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    /// 配置七牛 Secret Key
388    #[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    /// 配置七牛存储空间
395    #[inline]
396    pub fn bucket(mut self, bucket: impl Into<String>) -> Self {
397        self.0.bucket = bucket.into();
398        self
399    }
400
401    /// 配置 IO 服务器 URL 列表
402    #[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    /// 配置 UC 服务器域名列表
409    #[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    /// 配置监控服务器域名列表,如果不配置或配置为空,则不会启用打点功能
416    #[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    /// 是否使用 Getfile API,默认为 true
423    #[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    /// 是否对 key 进行格式化,默认为 false
430    #[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    /// 是否使用私有存储空间,默认不使用
437    #[inline]
438    pub fn private(mut self, private: Option<bool>) -> Self {
439        self.0.private = private;
440        self
441    }
442
443    /// 配置 IO 和 UC 服务器访问重试次数,默认为 10
444    #[inline]
445    pub fn retry(mut self, retry: Option<usize>) -> Self {
446        self.0.retry = retry;
447        self
448    }
449
450    /// 配置域名访问失败后的惩罚时长,默认为 30 分钟
451    #[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    /// 配置域名访问的基础超时时长,默认为 3000 毫秒
458    #[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    /// 配置域名连接的超时时长,默认为 50 毫秒
465    #[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    /// 配置最大并行重试次数,默认为 5,如果设置为 Some(0) 则表示禁止并行重试功能
473    #[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    /// 设置打点记录上传频率,默认为 10 秒
480    #[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    /// 设置打点记录本地缓存文件尺寸上限,默认为 1 MB
487    #[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 {}