8个版本
0.3.1 | 2023年9月14日 |
---|---|
0.3.0 | 2023年9月13日 |
0.2.4 | 2023年9月14日 |
0.2.3 | 2023年3月14日 |
0.1.0 | 2022年6月7日 |
#5 在 #backoff
8,204 每月下载量
38KB
395 行
futures-retry-policies
一个帮助重试Futures的crate。
use futures_retry_policies::{retry, RetryPolicy};
use std::{ops::ControlFlow, time::Duration};
// 1. Create your retry policy
/// Retries a request n times
pub struct Retries(usize);
// 2. Define how your policy behaves
impl RetryPolicy<Result<(), &'static str>> for Retries {
fn should_retry(&mut self, result: Result<(), &'static str>) -> ControlFlow<Result<(), &'static str>, Duration> {
if self.0 > 0 && result.is_err() {
self.0 -= 1;
// continue to retry on error
ControlFlow::Continue(Duration::from_millis(100))
} else {
// We've got a success, or we've exhausted our retries, so break
ControlFlow::Break(result)
}
}
}
/// Makes a request, like a HTTP request or gRPC request which you want to retry
async fn make_request() -> Result<(), &'static str> {
// make a request
# static COUNT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
# if COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst) < 2 { Err("fail") } else { Ok(()) }
}
#[tokio::main]
async fn main() -> Result<(), &'static str> {
// 3. Await the retry with your policy, a sleep function, and your async function.
retry(Retries(3), tokio::time::sleep, make_request).await
}
跟踪
添加 tracing
功能,您可以使用 Traced
RetryPolicy来自动记录您的重试
Tokio
添加 tokio
功能,您可以使用便捷的tokio重试方法来跳过指定 tokio::time::sleep
。
您还可以使用 tokio::RetryFutureExt
trait来支持在异步函数上直接调用 retry
。
#[tokio::main]
async fn main() -> Result<(), &'static str> {
make_request.retry(Retries(3)).await
}
重试策略
此crate对 retry-policies crate
提供了一等支持
use futures_retry_policies::{retry, retry_policies::{ShouldRetry, RetryPolicies}};
use retry_policies::policies::ExponentialBackoff;
enum Error { Retry, DoNotRetry }
impl ShouldRetry for Error {
fn should_retry(&self, _: u32) -> bool { matches!(self, Error::Retry) }
}
async fn make_request() -> Result<(), Error> {
// make a request
# static COUNT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
# if COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst) < 2 { Err(Error::Retry) } else { Ok(()) }
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let backoff = ExponentialBackoff::builder().build_with_max_retries(3);
let policy = RetryPolicies::new(backoff);
retry(policy, tokio::time::sleep, make_request).await
}
依赖项
~4–11MB
~103K SLoC