pub async fn join_bounded<F, T>(futures: Vec<F>, limit: usize) -> Vec<T>where
F: Future<Output = T>,Expand description
Run a list of futures with bounded concurrency via Arc<Semaphore>.
Gate of record (rules_rust_paralelismo): each future acquires one permit with
Semaphore::acquire_owned before polling body work; the permit is dropped
(RAII) when the future completes. Internally composed with
buffer_unordered so the stream polls at most limit futures, and the
Semaphore is the admission control agents / tests observe.
Results are returned in completion order. Prefer this over unbounded
join_all on collections of unknown size.
§Cancel safety
Each future is polled independently; dropping the returned future cancels in-flight work at the next await point of those futures (permits return).
§Observability
Host-local only: tracing::debug! of available_permits at start (no remote
OTel — product law).
§Gate pattern
Uses Semaphore::acquire (not acquire_owned) because callers pass
borrowed CDP futures that are not 'static. Work stays on the same
poller (buffer_unordered); permit is held for the future body and dropped
via RAII. For tokio::spawn fan-out, call sites use acquire_owned +
JoinSet instead (batch/crawl).