-2

The function run_av_check receives a vector filled with URLs which need to get called using reqwest. Iterating through the URLs gives me the error that the borrowed value does not live long enough. My understanding is that as long as check_availability is not finished for all URLs which are called in run_av_check using a for loop the run_av_check function is not finished, therefore the variable URLs should still exist during the runtime of all check_availibility calls.

I have read the Tokio and Rust documentation but I am not able to find a clue how and why this behaviour occurs. Why does the error pop up and what needs to be changed to make this work, both program wise and in my way of thinking?

async fn check_availability(host: &str) -> Result<reqwest::StatusCode, reqwest::Error> {
    // ... building url
    match client.get(&url).send().await {
        Ok(r) => Ok(r.status()),
        Err(_e) => Ok(reqwest::StatusCode::GATEWAY_TIMEOUT),
    }
}

async fn run_av_check(urls: Vec<std::string::String>) -> Result<AvResponse, AvError> {
    let mut av_urls: Vec<std::string::String> = vec![];
    let mut s: std::string::String = "".to_string();
    let mut attributes = Vec::new();

    for url in urls.iter() {
        attributes.push(("instance", url));
        let resp = tokio::task::spawn(check_availability(url));
        // ... processing result
        let res = AvResponse {
            av_urls,
            prom_details: s,
        };
        Ok(res)
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Timo
  • 429
  • 3
  • 12
  • 1
    It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Sep 29 '20 at 12:30
  • 1
    Please [edit] your question and paste the exact and entire error that you're getting — that will help us to understand what the problem is so we can help best. Sometimes trying to interpret an error message is tricky and it's actually a different part of the error message that's important. Please use the message from running the compiler directly, not the message produced by an IDE, which might be trying to interpret the error for you. – Shepmaster Sep 29 '20 at 12:30
  • Skimming your code, maybe the problem is in `for url in urls.iter()`... Try `for url in urls` and and switch `check_availability` into taking a `String`. – rodrigo Sep 29 '20 at 13:27

1 Answers1

-1

The problem is that you are starting independent tasks in tokio::task::spawn(check_availability(url));

This function takes only 'static references but your url refers to the local vector urls.

You need to make check_availability accept the String type (fn check_availability(host: String)) and call it like let resp = tokio::task::spawn(check_availability(url.to_string()));

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366