amazon_spapi/apis/
configuration.rs1use reqwest::{retry, Client, Error, Request, Response};
2use std::{cell::RefCell, ops::Deref};
3
4#[derive(Debug, Clone)]
5pub struct CustomClient {
6 inner: Client,
7 retry_count: usize,
8}
9
10impl CustomClient {
11 pub fn new(client: Client, retry_count: usize) -> Self {
12 Self { inner: client, retry_count }
13 }
14
15 pub async fn execute(&self, request: Request) -> Result<Response, Error> {
16 log::debug!("Executing request to: {}", request.url());
17 log::debug!("Executing request method: {}", request.method());
18 log::debug!("Executing request headers: {:?}", request.headers());
19 log::debug!("Executing request body: {:?}", request.body());
20
21 if self.retry_count == 0 {
22 let result = self.inner.execute(request).await;
23 log::debug!("Response status: {:?}", result.as_ref().map(|r| r.status()));
24 log::debug!(
25 "Response headers: {:?}",
26 result.as_ref().map(|r| r.headers())
27 );
28 return result;
29 } else {
30 let mut last_result = None;
31
32 for i in 0..self.retry_count {
33 let request_clone = match request.try_clone() {
35 Some(req) => req,
36 None => {
37 return self.inner.execute(request).await;
39 }
40 };
41
42 let result = self.inner.execute(request_clone).await;
43
44 match &result {
45 Ok(response) => {
46 let status = response.status();
47 if status == reqwest::StatusCode::TOO_MANY_REQUESTS {
49 log::warn!(
50 "Received 429 status, retrying in {} seconds (attempt {}/{})",
51 (i + 1) * 2,
52 i + 1,
53 self.retry_count
54 );
55 tokio::time::sleep(tokio::time::Duration::from_secs(((i + 1) * 2) as u64)).await;
56 last_result = Some(result);
57 continue;
58 } else {
59 return result;
61 }
62 }
63 Err(_) => {
64 return result;
66 }
67 }
68 }
69
70 match last_result {
72 Some(res) => res,
73 None => self.inner.execute(request).await,
74 }
75 }
76 }
77}
78
79impl Deref for CustomClient {
80 type Target = Client;
81
82 fn deref(&self) -> &Self::Target {
83 &self.inner
84 }
85}
86
87#[derive(Debug, Clone)]
88pub struct Configuration {
89 pub base_path: String,
90 pub user_agent: Option<String>,
91 pub client: CustomClient,
92}