qiniu_download/async_api/
req_id.rs1use hyper::header::HeaderValue;
2use std::{
3 convert::{TryFrom, TryInto},
4 sync::atomic::{AtomicU64, Ordering::Relaxed},
5 time::{Duration, SystemTime, UNIX_EPOCH},
6};
7
8static START_TIME: AtomicU64 = AtomicU64::new(0);
9
10pub fn set_download_start_time(t: SystemTime) {
12 START_TIME.store(
13 t.duration_since(UNIX_EPOCH)
14 .map_or(0, |n| n.as_millis().try_into().unwrap_or(u64::MAX)),
15 Relaxed,
16 )
17}
18
19pub fn total_download_duration(t: SystemTime) -> Duration {
21 let end_time: u64 = t
22 .duration_since(UNIX_EPOCH)
23 .map_or(0, |n| n.as_millis().try_into().unwrap_or(u64::MAX));
24 Duration::from_millis(end_time - START_TIME.load(Relaxed))
25}
26
27pub(crate) const REQUEST_ID_HEADER: &str = "X-ReqId";
28
29pub(crate) fn get_req_id(tn: SystemTime, tries: usize, timeout: Duration) -> HeaderValue {
30 let (start_time, delta) = get_start_time_and_delta(tn);
31 HeaderValue::try_from(format!(
32 "r{}-{}-t{}-o{}",
33 start_time,
34 delta,
35 tries,
36 timeout.as_millis()
37 ))
38 .expect("Unexpected invalid header value")
39}
40
41pub(crate) fn get_req_id2(
42 tn: SystemTime,
43 tries: usize,
44 async_task_id: u32,
45 timeout: Duration,
46) -> HeaderValue {
47 let (start_time, delta) = get_start_time_and_delta(tn);
48 HeaderValue::try_from(format!(
49 "r{}-{}-t{}-a{}-o{}",
50 start_time,
51 delta,
52 tries,
53 async_task_id,
54 timeout.as_millis()
55 ))
56 .expect("Unexpected invalid header value")
57}
58
59fn get_start_time_and_delta(tn: SystemTime) -> (u64, u128) {
60 let start_time: u64 = START_TIME.load(Relaxed);
61 let end_time: u128 = tn.duration_since(UNIX_EPOCH).map_or(0, |n| n.as_nanos());
62 let delta: u128 = end_time - u128::from(start_time) * 1000 * 1000;
63 (start_time, delta)
64}