【问题标题】:Rust async-await: check if any future in a list resolves to true concurrently?Rust async-await:检查列表中的任何未来是否同时解析为真?
【发布时间】:2019-10-04 22:22:37
【问题描述】:

我正在尝试在 Rust async-await(即将稳定)中同时(而不是按顺序)运行期货列表,直到其中任何一个解析为 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() 组合。

我该怎么办?

【问题讨论】:

  • 我认为select 宏的问题在于,您需要为每个可能完成的未来分支。也许futures::future::select_ok 更好?
  • 谢谢!我认为select 需要首先覆盖并产生所有分支,但select_ok 显然不需要,它允许提前返回,所以这是完美的。

标签: concurrency rust async-await


【解决方案1】:

我认为您应该能够使用 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
}

【讨论】:

  • 非常感谢!我想明确指出boxed() 用于Pin 值,这是select_ok 所要求的。
猜你喜欢
  • 2013-06-08
  • 2019-03-21
  • 2019-11-04
  • 2016-02-16
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
相关资源
最近更新 更多