Rust异步等待:检查列表中是否有将来同时解析为true?

时间:2019-10-04 10:01:15

标签: concurrency rust async-await

我正试图在Rust异步等待(即将稳定)中同时(而不是按顺序)运行一个期货列表,直到其中任何一个解析为true

想象一下,有一个Vec<File>,并且将来每个文件运行一个会产生bool(可能是无序的)的情况。这将是一个简单的序列化实现。

async fn my_function(files: Vec<File>) -> bool {
    // Run the future on each file, return early if we received true
    for file in files {
        if long_future(file).await {
            return true;
        }
    }

    false
}

async fn long_future(file: File) -> bool {
    // Some long-running task here...
}

这可行,但是我想同时运行其中的一些期货以加快流程。我碰到了buffer_unordered()(在Stream上),但不知道如何实现。

据我了解,假设您提供了多线程池,则类似join的东西也可以同时运行期货。但是我不知道如何在这里有效地使用它。

我尝试了类似的方法,但是无法使它起作用:

let any_true = futures::stream::iter(files)
    .buffer_unordered(4) // Run up to 4 concurrently
    .map(|file| long_future(file).await)
    .filter(|stop| stop) // Only propagate true values
    .next() // Return early on first true
    .is_some();

此外,我正在寻找迭代器中使用的类似any的东西,以替换if语句或filter().next().is_some()的组合。

我将如何处理?

1 个答案:

答案 0 :(得分:2)

我认为您应该能够使用select_ok,就像Some Guy提到的那样。一个示例,其中我用一堆u32替换了文件进行说明:

use futures::future::FutureExt;

async fn long_future(file: u32) -> bool {
    true
}

async fn handle_file(file: u32) -> Result<(), ()> {
    let should_stop = long_future(file).await;
    // Would be better if there were something more descriptive here
    if should_stop {
        Ok(())
    } else {
        Err(())
    }
}

async fn tims_answer(files: Vec<u32>) -> bool {
    let waits = files.into_iter().map(|f| handle_file(f).boxed());

    let any_true = futures::future::select_ok(waits).await.is_ok();

    any_true
}