#tower-layer #backoff #tower #requests #strategy #retries #async-await

backoff-tower

一个用于将回退策略应用于重试请求的tower层

2个版本

0.1.6 2023年8月6日
0.1.5 2023年8月6日

#3#retries

32 每月下载量

MIT 许可证

17KB
371

backoff-tower

一个用于将回退策略应用于重试请求的tower层

概述

tower 内置了一个 RetryLayer,它会立即重试请求。 BackoffLayer 是一个围绕 RetryLayer 的包装器,它将 BackoffStrategy 应用于请求,以便在重试之前有一个延迟。支持 tokioasync-std,默认情况下选择 tokio

#[derive(Clone)]
struct MyPolicy {
    attempts_left: usize,
}

impl Policy<usize, usize, &'static str> for MyPolicy {
    type Future = Ready<Self>;

    fn retry(&self, _req: &usize, result: Result<&usize, &&'static str>) -> Option<Self::Future> {
        if self.attempts_left == 0 {
            return None;
        }

        match result {
            Ok(_) => None,
            Err(_) => Some(ready(MyPolicy { attempts_left: self.attempts_left - 1 }))
        }
    }

    fn clone_request(&self, req: &usize) -> Option<usize> {
        Some(req + 1)
    }
}

#[tokio::main]
async fn main() {
    let mut service = ServiceBuilder::new()
        .layer(BackoffLayer::new(MyPolicy { attempts_left: 8 }, ExponentialBackoffStrategy))
        .service_fn(|x: usize| async move {
            if x % 10 == 0 {
                Ok(x / 10)
            } else {
                Err("bad input")
            }
        });

    assert_eq!(Ok(6), service.call(55).await, "should be the next multiple of 10 divided by 10");
    assert_eq!(Err("bad input"), service.call(51).await, "retry limit should have been hit");
}

依赖

~2–15MB
~137K SLoC