(attempt: u32, error: Option<&ApiErrorInfo>)
| 21 | } |
| 22 | |
| 23 | pub fn delay(attempt: u32, error: Option<&ApiErrorInfo>) -> u64 { |
| 24 | if let Some(err) = error { |
| 25 | if let Some(ref headers) = err.response_headers { |
| 26 | if let Some(retry_after_ms) = headers.get("retry-after-ms") { |
| 27 | if let Ok(parsed_ms) = retry_after_ms.parse::<f64>() { |
| 28 | return parsed_ms as u64; |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | if let Some(retry_after) = headers.get("retry-after") { |
| 33 | if let Ok(parsed_seconds) = retry_after.parse::<f64>() { |
| 34 | return (parsed_seconds * 1000.0).ceil() as u64; |
| 35 | } |
| 36 | |
| 37 | if let Ok(parsed_date) = chrono::DateTime::parse_from_rfc2822(retry_after) { |
| 38 | let now = chrono::Utc::now(); |
| 39 | let diff = parsed_date.with_timezone(&chrono::Utc) - now; |
| 40 | if diff.num_milliseconds() > 0 { |
| 41 | return diff.num_milliseconds() as u64; |
| 42 | } |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | return RETRY_INITIAL_DELAY * RETRY_BACKOFF_FACTOR.pow(attempt - 1); |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | let calculated = RETRY_INITIAL_DELAY * RETRY_BACKOFF_FACTOR.pow(attempt - 1); |
| 51 | calculated.min(RETRY_MAX_DELAY_NO_HEADERS) |
| 52 | } |
| 53 | |
| 54 | #[derive(Debug, Clone)] |
| 55 | pub struct ApiErrorInfo { |
no test coverage detected