asynchronousrustasync-awaitrust-futures

Rust parallel dowload doesn't execute chaining async call


I've been struggling to make this store_result got executed in this method chaining:

let (tasks, files): (Vec<_>, Vec<_>) = result_files
    .into_iter()
    .filter(|x| should_download_file(&provider_id_path, x.filename.clone()))
    .map(download_file)
    .unzip();

let results = future::join_all(tasks).await;

let store_result = |x: (Result<Response, Error>, Result<File, std::io::Error>)| async {
    //info!("Storing result: {:?}, {:?}", x.0, x.1);

    // make sure both are Oks
    let (result, file) = match (x.0, x.1) {
        (Ok(result), Ok(file)) => {
            info!("Got result and file.");
            info!("Result: {:?}", result.url());
            info!("File: {:?}", file);
            (result, file)
        }
        _ => {
            error!("Failed to get result and file.");
            return;
        }
    };
    // Write bytes to file
    let _ = write_bytes_to_file(file, result).await;
};

// Map result and file to store_result
let _ = results
    .into_iter()
    .zip(files)
    .map(|x| async {
      debug!("Storing result: {:?}, {:?}", x.0, x.1);
        let _ = store_result(x).await;
    })
    .collect::<Vec<_>>();

info!("Batch download done.");

The future::join_all(tasks).await; got executed correctly. What's wrong with the code?


Solution

  • I've been through this before but somehow I missed it:

    // Map result and file to store_result
    let store_results = results
        .into_iter()
        .zip(files)
        .map(|x| async {
            debug!("Storing result: {:?}, {:?}", x.0, x.1);
            let _ = store_result(x).await;
        })
        .collect::<Vec<_>>();
    
    let _ = future::join_all(store_results).await;