From 7a32696f906d7c887c06d96eb3811fb226a09632 Mon Sep 17 00:00:00 2001 From: Malte Janz Date: Sat, 29 Jun 2024 22:06:38 +0200 Subject: [PATCH] SwClient timings + in flight limit fixes --- CHANGELOG.md | 4 ++++ src/api.rs | 43 ++++++++++++++++++++++--------------------- src/main.rs | 4 ++-- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4303b3e..9596550 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # NEXT-RELEASE - "To-One-Association" values are now imported correctly + - Added profile `product_with_manufacturer.yaml` as an example +- Fixed reported request timings (they were measured wrong, longer than actual) +- Fixed `--in-flight-limit` to actually be respected (wasn't implemented correctly) +- Changed default `in_flight_limit` to `8` (from `16`) as that seemed like a better performing number # v0.3.0 - Added `associations` entry for schema (used on export only) diff --git a/src/api.rs b/src/api.rs index 5341d72..7426f43 100644 --- a/src/api.rs +++ b/src/api.rs @@ -26,12 +26,13 @@ impl SwClient { // and that doesn't have the association data as part of the entity object default_headers.insert(header::ACCEPT, HeaderValue::from_static("application/json")); let client = Client::builder() - .timeout(Duration::from_secs(10)) + .timeout(Duration::from_secs(15)) .default_headers(default_headers) .build()?; let credentials = Arc::new(credentials); let auth_response = Self::authenticate(&client, credentials.as_ref()).await?; + println!("Shopware API client with in_flight_limit={} created and authenticated", in_flight_limit); Ok(Self { client, in_flight_semaphore: Arc::new(Semaphore::new(in_flight_limit)), @@ -47,7 +48,6 @@ impl SwClient { payload: &[T], ) -> Result<(), SwApiError> { let entity: String = entity.into(); - let start_instant = Instant::now(); println!( "sync {:?} '{}' with payload size {}", action, @@ -65,8 +65,9 @@ impl SwClient { }; let response = { - let _lock = self.in_flight_semaphore.acquire(); - self.client + let _lock = self.in_flight_semaphore.acquire().await.unwrap(); + let start_instant = Instant::now(); + let res = self.client .post(format!("{}/api/_action/sync", self.credentials.base_url)) .bearer_auth(access_token) .header("single-operation", 1) @@ -74,7 +75,12 @@ impl SwClient { .header("sw-skip-trigger-flow", 1) .json(&body) .send() - .await? + .await?; + println!( + "sync request finished after {} ms", + start_instant.elapsed().as_millis() + ); + res }; if !response.status().is_success() { @@ -83,11 +89,6 @@ impl SwClient { return Err(SwApiError::Server(status, body)); } - println!( - "sync finished after {} ms", - start_instant.elapsed().as_millis() - ); - Ok(()) } @@ -97,7 +98,7 @@ impl SwClient { // ToDo: implement retry on auth fail let access_token = self.access_token.lock().unwrap().clone(); let response = { - let _lock = self.in_flight_semaphore.acquire(); + let _lock = self.in_flight_semaphore.acquire().await.unwrap(); self.client .get(format!( "{}/api/_info/entity-schema.json", @@ -130,7 +131,7 @@ impl SwClient { let access_token = self.access_token.lock().unwrap().clone(); let response = { - let _lock = self.in_flight_semaphore.acquire(); + let _lock = self.in_flight_semaphore.acquire().await.unwrap(); self.client .post(format!( "{}/api/search/{}", @@ -175,15 +176,15 @@ impl SwClient { entity: &str, criteria: &Criteria, ) -> Result { - let start_instant = Instant::now(); // entity needs to be provided as kebab-case instead of snake_case let entity = entity.replace('_', "-"); // ToDo: implement retry on auth fail let access_token = self.access_token.lock().unwrap().clone(); let response = { - let _lock = self.in_flight_semaphore.acquire(); - self.client + let _lock = self.in_flight_semaphore.acquire().await.unwrap(); + let start_instant = Instant::now(); + let res = self.client .post(format!( "{}/api/search/{}", self.credentials.base_url, entity @@ -191,7 +192,12 @@ impl SwClient { .bearer_auth(access_token) .json(criteria) .send() - .await? + .await?; + println!( + "search request finished after {} ms", + start_instant.elapsed().as_millis() + ); + res }; if !response.status().is_success() { @@ -202,11 +208,6 @@ impl SwClient { let value: SwListResponse = Self::deserialize(response).await?; - println!( - "search request finished after {} ms", - start_instant.elapsed().as_millis() - ); - Ok(value) } diff --git a/src/main.rs b/src/main.rs index e0956b3..e530532 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,7 +60,7 @@ enum Commands { verbose: bool, /// How many requests can be "in-flight" at the same time - #[arg(short, long, default_value = "16")] + #[arg(short, long, default_value = "8")] in_flight_limit: usize, }, } @@ -138,7 +138,7 @@ async fn auth(domain: String, id: String, secret: String) -> anyhow::Result<()> }; // check if credentials work - let _ = SwClient::new(credentials.clone(), 16).await?; + let _ = SwClient::new(credentials.clone(), 8).await?; // write them to file let serialized = toml::to_string(&credentials)?;