【问题标题】:How to race collection of futures in Rust and with retry如何在 Rust 中竞速收集期货并重试
【发布时间】:2022-12-12 18:20:42
【问题描述】:

我有一个 Futures 集合,我想执行所有 Futures 并获得第一个成功解析并中止其他仍在处理中的 Futures 。

但我想处理第一个解决的未来实际返回无效值的情况,从而导致需要重试的情况。

我从 tokio 找到了 select! 宏,但它不支持竞速一系列期货。使用 select! 需要明确列出将要比赛的期货......使其不适用于我的用例。我也没有看到它支持任何重试机制。

那么我如何在 Rust 中竞速收集 futures 并重试呢?

【问题讨论】:

    标签: rust async-await rust-tokio


    【解决方案1】:

    如果你的期货返回Result,你需要在Err上重试,“重试”并不是要重试失败的期货,而是要尝试其他期货,你可以使用futures'select_ok()

    async fn first_successful<T, E: fmt::Debug, Fut>(futures: Vec<Fut>) -> T
    where
        E: fmt::Debug,
        Fut: Future<Output = Result<T, E>> + Unpin,
    {
        let (output, _remaining_futures) = futures::future::select_ok(futures)
            .await
            .expect("all futures failed");
        output
    }
    

    如果没有,你需要更多的控制,你可以使用强大的FuturesUnordered。例如,使用自定义谓词尝试其他人:

    use futures::stream::StreamExt;
    
    async fn first_successful<Fut: Future + Unpin>(
        futures: Vec<Fut>,
        mut failed: impl FnMut(&Fut::Output) -> bool,
    ) -> Fut::Output {
        let mut futures = futures::stream::FuturesUnordered::from_iter(futures);
        while let Some(v) = futures.next().await {
            if !failed(&v) {
                return v;
            }
        }
        panic!("all futures failed");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      • 2022-11-06
      • 2021-05-04
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      相关资源
      最近更新 更多