我必须重试异步函数 -
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
,但我仍然遇到相同的错误。
是否可以在重试块内使用异步函数?
正如您在源代码中看到的那样,重试箱不处理异步期货。另一种,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())
);