From 0842b4d0bca3a87d5378fc4e5255d5eae2d98975 Mon Sep 17 00:00:00 2001 From: buckn Date: Tue, 14 Oct 2025 16:25:51 -0400 Subject: [PATCH] ud --- Cargo.lock | 119 ++++++++--------------------------------------------- src/lib.rs | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba23bf9..2d06aa2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "anyhow" version = "1.0.100" @@ -40,21 +25,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link 0.2.1", -] - [[package]] name = "base64" version = "0.22.1" @@ -243,30 +213,24 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - [[package]] name = "h2" version = "0.4.12" @@ -552,17 +516,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -646,15 +599,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" version = "1.0.4" @@ -662,7 +606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "windows-sys 0.59.0", ] @@ -693,15 +637,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -853,7 +788,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand", "ring", @@ -922,7 +857,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -936,9 +871,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64", "bytes", @@ -992,12 +927,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -1195,12 +1124,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -1274,7 +1203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys 0.61.2", @@ -1327,29 +1256,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", "socket2", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -1555,15 +1481,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" diff --git a/src/lib.rs b/src/lib.rs index 073e002..59689da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -338,3 +338,90 @@ where .await } +/// Execute a list of ApiDispatch objects concurrently using a shared Client and Keys. +/// - `dispatches`: vector of dispatchable objects (Arc). +/// - `client`: shared reqwest client (Arc) — cloned for each task cheaply. +/// - `keys`: shared keys (Arc). +/// - `override_url` and `sandbox` forwarded to each dispatch call. +/// - `concurrency_limit`: optional cap; if None, uses SEMAPHORE global limit. +/// +/// Returns flattened Vec> (each dispatch may yield multiple Values). +/// Execute a list of ApiDispatch objects concurrently using a shared Client and Keys. +pub async fn execute_dispatches_concurrent( + dispatches: Vec< + Arc< + dyn ApiDispatch< + Request = (), + Response = serde_json::Value, + Error = anyhow::Error, + >, + >, + >, + client: Arc, + keys: Arc, + override_url: Option<&str>, + sandbox: bool, + concurrency_limit: Option, +) -> anyhow::Result>> { + use tokio::task::JoinSet; + use std::sync::Arc; + + // Optional per-call semaphore (create local one if a specific limit is provided) + let local_sem = concurrency_limit.map(|n| Arc::new(Semaphore::new(n))); + + let mut set = JoinSet::new(); + + for dispatch in dispatches.into_iter() { + let client = client.clone(); + let keys = keys.clone(); + let override_url = override_url.map(|s| s.to_string()); + let local_sem_clone = local_sem.clone(); + let dispatch_arc = dispatch.clone(); + + set.spawn(async move { + // ✅ FIXED: use acquire_owned() so permit owns the semaphore Arc + let _permit = if let Some(ls) = local_sem_clone { + let sem = Arc::clone(&ls); + let p = sem.acquire_owned().await.expect("local semaphore poisoned"); + Some(p) + } else { + let sem = Arc::clone(&SEMAPHORE); + let p = sem.acquire_owned().await.expect("global semaphore poisoned"); + Some(p) + }; + + // Call send_all (each dispatch returns Vec>) + let res = dispatch_arc + .send_all( + client, + keys, + override_url.as_deref(), + sandbox, + None, // method_override not used here + ) + .await; + + match res { + Ok(vec_vals) => Ok(vec_vals), + Err(e) => Err(e), + } + }); + } + + // Collect results, flatten Vec>> -> Vec> + let mut out: Vec> = Vec::new(); + + while let Some(join_res) = set.join_next().await { + match join_res { + Ok(inner_res) => match inner_res { + Ok(vec_vals) => out.extend(vec_vals), + Err(e) => out.push(Err(e)), + }, + Err(join_err) => { + out.push(Err(anyhow::anyhow!("task join error: {}", join_err))); + } + } + } + + Ok(out) +}