如何在 Rust 的重试中使用异步闭包

问题描述 投票:0回答:1

我必须重试异步函数 -

handle_message
并且我正在使用 retry 板条箱(版本“1.2.1”)。但第二个参数是一个闭包。

use retry::{retry, delay::Fixed};

retry(Fixed::from_millis(10000).take(3), || async {
    let message = handle_message(my_message.clone()).await;

    match message {
        Ok(()) => info!("Message successfully registered"),
        Err(e) => {
            // For certain errors likely to resolve if we wait a bit, we schedule a retry
            if e.is_code(EC::MyErrorCode, true)
            {
                debug!("Handling message error- {:?}", e);
                return Err(format!("Dkg message w/ error: {:?}", e));
            }
        }
    }

    Ok(()) // Don't try any other errors
});

我收到以下错误:

the trait bound `OperationResult<_, _>: From<[async block@src/my_file.rs:xx:xx]>` is not satisfied
the trait `From<std::result::Result<T, E>>` is implemented for `OperationResult<T, E>`
required for `[async block@src/my_file.rs:xx:xx]` to implement `Into<OperationResult<_, _>>`

我也尝试从异步闭包返回

OperationResult::Ok/Err
而不是
Result::Ok/Err
,但我仍然遇到相同的错误。

是否可以在重试块内使用异步函数?

asynchronous rust scope closures retry-logic
1个回答
0
投票

正如您在源代码中看到的那样,重试箱不处理异步期货。另一种,tryhard 确实如此。检查

custom_backoff
方法:

use std::time::Duration;
use tryhard::RetryPolicy;

tryhard::retry_fn(|| read_file("Cargo.toml"))
    .retries(10)
    .custom_backoff(|attempt, error: &std::io::Error| {
        if error.to_string().contains("foobar") {
            // returning this will cancel the loop and
            // return the most recent error
            RetryPolicy::Break
        } else {
            RetryPolicy::Delay(Duration::from_millis(50))
        }
    })
    .await?;

如果迁移对您来说太多,请尝试“去异步”调用,阻塞当前线程。 tokio 的一个鼓舞人心的例子,可能应该用 spawn_blocking

 来推动 IO 向前发展:
let message = tokio::runtime::Handle::current().block_on( handle_message(my_message.clone()) );

© www.soinside.com 2019 - 2024. All rights reserved.