How to use async functions with join_all?

I have the following code:

    match join(db_eid_cache, table_eid_cache).await {
        (Ok(_v1), Ok(_v2)) => {
            info!(
                "Successfully updated db_eid_cache, table_eid_cache caches at: {}",
                utc_now()
            )
        }
        _ => error!("Could not update some caches"),
    };

The type of each functions that are joined:

let db_eid_cache: impl Future<Output = Result<String, Box<dyn Error + Send + Sync>>>

When I try to use join_all instead of join:

❯ cargo build
   Compiling cache-manager v0.1.0 (/Users/l1x/code/datadeft/depoxy/etl/jobs/lambda/cache-manager)
error[E0308]: mismatched types
  --> src/cache_manager.rs:96:39
   |
96 |     match join_all(vec![db_eid_cache, table_eid_cache]).await {
   |                                       ^^^^^^^^^^^^^^^ expected opaque type, found a different opaque type
   |
note: while checking the return type of the `async fn`
  --> src/db_eid_cache.rs:9:79
   |
9  | pub async fn create_db_eid_cache(aws_clients: AwsClients, config: &Config) -> Ret {
   |                                                                               ^^^ checked the `Output` of this `async fn`, expected opaque type
note: while checking the return type of the `async fn`
  --> src/table_eid_cache.rs:14:6
   |
14 | ) -> Result<String, Box<dyn error::Error + Send + Sync>> {
   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, found opaque type
   = note: expected opaque type `impl futures::Future<Output = Result<std::string::String, Box<(dyn StdError + Sync + std::marker::Send + 'static)>>>` (opaque type at <src/db_eid_cache.rs:9:79>)
              found opaque type `impl futures::Future<Output = Result<std::string::String, Box<(dyn StdError + Sync + std::marker::Send + 'static)>>>` (opaque type at <src/table_eid_cache.rs:14:6>)
   = help: consider `await`ing on both `Future`s
   = note: distinct uses of `impl Trait` result in different opaque types

error[E0308]: mismatched types
  --> src/cache_manager.rs:97:9
   |
96 |     match join_all(vec![db_eid_cache, table_eid_cache]).await {
   |           --------------------------------------------------- this expression has type `Vec<Result<std::string::String, Box<dyn StdError + Sync + std::marker::Send>>>`
97 |         (Ok(_v1), Ok(_v2)) => {
   |         ^^^^^^^^^^^^^^^^^^ expected struct `Vec`, found tuple
   |
   = note: expected struct `Vec<Result<std::string::String, Box<dyn StdError + Sync + std::marker::Send>>>`
               found tuple `(_, _)`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `cache-manager` due to 2 previous errors

It seems that join_all have a slightly different semantics to join and co. Is there a easy way to make these opaque type issues work with join_all?

You could box them, but its easier to use tokio::join! instead of join_all.

match tokio::join!(db_eid_cache, table_eid_cache) {
    ...
}

Thanks @alice. This works.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.