1

My code can be boiled down to the following:

let client = reqwest::Client::new();
let endpoints = vec!['http://google.com', 'http://www.yahoo.com', 'http://example.com'];
let futures: Vec<_> = endpoints.iter().map(|endpoint| {
            return client
                .get(endpoint)).send();
}).collect();

let (item_resolved, _remaining_futures, _last) = select_all(futures).await;
let mut responses = vec![];

for item in item_resolved {
    responses.push(item.json::<ResponseStruct>().await);
}

dbg!(responses);

problem is responses only contain one result. I expect it to be a vec of results from calling the endpoints.

Finlay Weber
  • 2,989
  • 3
  • 17
  • 37
  • `select_all()` gives the first result. Maybe you want [`join_all()`](https://docs.rs/futures/latest/futures/future/fn.join_all.html)? – Chayim Friedman Dec 12 '22 at 14:27
  • damn! I thought if `select_ok` gives the first result, then `select_all` should get ALL the results! – Finlay Weber Dec 12 '22 at 14:28
  • Nope, `select_all()` gives the first result, `select_ok()` gives the first _successful_ result. `select()` gives the first result of only two futures. – Chayim Friedman Dec 12 '22 at 14:29
  • If you want all successful results, try [`try_join_all()`](https://docs.rs/futures/latest/futures/future/fn.try_join_all.html). – Chayim Friedman Dec 12 '22 at 14:31
  • I think I want a join_all but with the ability to know which endpoints resulted in an error. – Finlay Weber Dec 12 '22 at 14:35
  • So you just need to check? – Chayim Friedman Dec 12 '22 at 14:37
  • I guess. I am not just sure how to link back the results to the corresponding endpoint because I do not think the result is guaranteed to be in the same order as the endpoints in the collections. And this is needed for error reporting for instance. To know which of the endpoints actually failed – Finlay Weber Dec 12 '22 at 15:05
  • You can attach this information to the future. – Chayim Friedman Dec 12 '22 at 15:32
  • Sorry but how do I do that? In my case I am using `reqwest` to make the `http` call. I am not sure where to attach extra information to the `Future` – Finlay Weber Dec 12 '22 at 15:34
  • `async { (fut.await, url) }`. – Chayim Friedman Dec 12 '22 at 16:07
  • sorry if this is a noob response. But that does not work. I start with `let futures: Vec<_> = endpoints.iter().map(|endpoint| { reqwest.send(endpoint)})` which gives me a collection of Futures, and then I do `let raw_responses = join_all(futures).await;`. I am not sure where I can attach the info about the endpoint to the future – Finlay Weber Dec 12 '22 at 16:14
  • Instead of `map(|endpoint| { reqwest.send(endpoint)})` do `map(|endpoint| async { (reqwest.send(endpoint).await, url) })` and then each response is a tuple of `(response, url)`. – Chayim Friedman Dec 12 '22 at 16:15

1 Answers1

0

This can be achieved with FuturesUnordered from the futures crate.

Here's an example I just shared from another answer: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7f2faf54cec2267b7c6b0839439dea0d

SeedyROM
  • 2,203
  • 1
  • 18
  • 22