@sjcrh/proteinpaint-rust 2.191.4 → 2.191.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/gdcmaf.rs +40 -18
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.191.4",
2
+ "version": "2.191.6",
3
3
  "name": "@sjcrh/proteinpaint-rust",
4
4
  "type": "module",
5
5
  "description": "Rust-based utilities for proteinpaint",
package/src/gdcmaf.rs CHANGED
@@ -201,24 +201,46 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
201
201
  )) as Box<dyn std::error::Error>);
202
202
  };
203
203
 
204
+ let client = reqwest::Client::builder()
205
+ .timeout(Duration::from_secs(30)) // 30-second timeout per request
206
+ .connect_timeout(Duration::from_secs(15))
207
+ .pool_max_idle_per_host(0) // avoid "connection closed before message completed" race
208
+ .build()
209
+ .map_err(|e| {
210
+ let client_error = ErrorEntry {
211
+ url: String::new(),
212
+ error: format!("Client build error: {}", e),
213
+ };
214
+ let client_error_js = serde_json::to_string(&client_error)
215
+ .unwrap_or_else(|_| "{\"url\":\"\",\"error\":\"Failed to serialize client build error\"}".to_string());
216
+ writeln!(io::stderr(), "{}", client_error_js).expect("Failed to write client build error to stderr");
217
+ e
218
+ })?;
219
+
204
220
  //downloading maf files parallelly and merge them into single maf file
205
221
  let download_futures = futures::stream::iter(url.into_iter().map(|url| {
206
- let req_headers_clone = req_headers.clone();
222
+ let client = client.clone();
223
+ let req_headers = req_headers.clone();
207
224
  async move {
208
- let client = reqwest::Client::builder()
209
- .timeout(Duration::from_secs(60)) // 60-second timeout per request
210
- .connect_timeout(Duration::from_secs(15))
211
- .default_headers(req_headers_clone.clone())
212
- .build()
213
- .map_err(|_e| {
214
- let client_error = ErrorEntry {
215
- url: url.clone(),
216
- error: "Client build error".to_string(),
217
- };
218
- let client_error_js = serde_json::to_string(&client_error).unwrap();
219
- writeln!(io::stderr(), "{}", client_error_js).expect("Failed to build reqwest client!");
220
- });
221
- match client.unwrap().get(&url).send().await {
225
+ // bounded retry for transient transport failures
226
+ // (IncompleteMessage / TimedOut / connect), up to 3 attempts with backoff
227
+ let mut attempt: u32 = 0;
228
+ let send_result = loop {
229
+ attempt += 1;
230
+ let mut request = client.get(&url);
231
+ for (name, value) in req_headers.iter() {
232
+ request = request.header(name.clone(), value.clone()); // == .header("X-Forwarded-Agent", …) etc.
233
+ }
234
+ match request.send().await {
235
+ Ok(resp) => break Ok(resp),
236
+ Err(e) if attempt < 3 && (e.is_request() || e.is_timeout() || e.is_connect()) => {
237
+ tokio::time::sleep(Duration::from_millis(500 * attempt as u64)).await;
238
+ continue;
239
+ }
240
+ Err(e) => break Err(e),
241
+ }
242
+ };
243
+ match send_result {
222
244
  Ok(resp) if resp.status().is_success() => match resp.bytes().await {
223
245
  Ok(content) => {
224
246
  let mut decoder = GzDecoder::new(&content[..]);
@@ -240,11 +262,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
240
262
  }
241
263
  },
242
264
  Ok(resp) => {
243
- let error_msg = format!("HTTP error: {}", resp.status());
265
+ let error_msg = format!("HTTP error: {:?}", resp.status());
244
266
  Err((url.clone(), error_msg))
245
267
  }
246
268
  Err(e) => {
247
- let error_msg = format!("Server request failed: {}", e);
269
+ let error_msg = format!("Server request failed: {:?}", e);
248
270
  Err((url.clone(), error_msg))
249
271
  }
250
272
  }
@@ -264,7 +286,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
264
286
  }
265
287
 
266
288
  download_futures
267
- .buffer_unordered(20)
289
+ .buffer_unordered(10)
268
290
  .for_each(|result| {
269
291
  let encoder = Arc::clone(&encoder); // Clone the Arc for each task
270
292
  let maf_col_cp = maf_col.clone();