2

I have the following code

main.rs

use futures::executor::block_on;
use futures::join;
use std::io;

mod file;

fn main() -> io::Result<()> {
    block_on(load_files());

    Ok(())
}

async fn load_files() {
    join!(load_file_1(), load_file_2());
}

async fn load_file_1() {
    let r1 = file::read_file("src/file1.txt").await;
    println!("file 1 size: {}", r1.unwrap().len());
}

async fn load_file_2() {
    let r2 = file::read_file("src/file2.txt").await;
    println!("file 2 size: {}", r2.unwrap().len());
}

file.rs

use std::fs::File;
use std::io::{self, Read};

pub async fn read_file(path: &str) -> io::Result<String> {
    let mut file = File::open(path)?;
    let mut buffer = String::new();
    file.read_to_string(&mut buffer)?;
    Ok(buffer)
}

My understanding is that by joining load_file_1 and load_file_2, they should execute concurrently. However, this is not the case. Putting a huge file1.txt file (around 5Gb), the program still blocks on load_file_1. This is not the case if I'm using async_std task::spawn function.

Is the problem in my code or in join!?

Omar Abid
  • 15,753
  • 28
  • 77
  • 108
  • join! just waits on (polls) both futures, whether they execute concurrently is a propertyof your executor. – Masklinn Jan 22 '20 at 11:52
  • 4
    Your `read_file` function doesn't seem to do anything asynchronously either, AFAIK Rust's async doesn't magically make existing APIs asynchronous so you need to use some sort of asynchronous file reading / loading API. Here you're running read_file, it blocks until it's read the entire file in memory (never yielding to the executor) and then reports completion once it's done. You need to use futures::io not std::io. – Masklinn Jan 22 '20 at 11:55
  • 3
    As @Masklinn said, `std` is synchronous, so you can't use it in `async` functions. You have to use eg. `async_std` or `tokio`'s file reading functions instead. – mcarton Jan 22 '20 at 11:59
  • @mcarton I'm a little bit confused. That's the gist I got (async functionality need to report back its readiness) but if you use async_std task::spawn with the exact same function, the code run concurrently. – Omar Abid Jan 22 '20 at 14:22
  • You are mostly likely using this feature of `async_std`: https://async.rs/blog/stop-worrying-about-blocking-the-new-async-std-runtime/ – mcarton Jan 22 '20 at 14:38

0 Answers0