#future #error #retry #stream #tokio #asynchronous-programming #io-error

futures-retry

重试您的 Futures 和 Streams!

11 个不稳定版本

0.6.0 2021 年 1 月 13 日
0.5.0 2020 年 2 月 25 日
0.4.0 2019 年 12 月 21 日
0.3.3 2019 年 4 月 27 日
0.1.2 2018 年 3 月 21 日

#263异步

Download history 17586/week @ 2024-03-14 11929/week @ 2024-03-21 26688/week @ 2024-03-28 12665/week @ 2024-04-04 13248/week @ 2024-04-11 18726/week @ 2024-04-18 20467/week @ 2024-04-25 18294/week @ 2024-05-02 19408/week @ 2024-05-09 30179/week @ 2024-05-16 30395/week @ 2024-05-23 26341/week @ 2024-05-30 29856/week @ 2024-06-06 24355/week @ 2024-06-13 32863/week @ 2024-06-20 26094/week @ 2024-06-27

118,784 每月下载量
26 个开源包 中使用(直接使用 12 个)

MIT/Apache

27KB
318

futures-retry

pipeline status crates.io docs.rs

[发布文档]

[主文档]

一个帮助您重试未来的工具 :) 严格来说,是 FutureStream

当您遇到错误时,这是一个相当常见的任务,无论是连接超时还是一些临时的操作系统错误。

在同步方式中执行任务时,实现尝试逻辑相当简单,但一到异步编程,您突然需要写一大堆样板代码,引入状态机等等。

这个库旨在使您的生活更加轻松,并让您编写更简洁、更优雅的代码,专注于业务逻辑而不是处理所有乱七八糟的事情。

我在看到 hyper 问题 后受到启发编写了这个库,并且我意识到这个问题比我以前认为的更普遍。

有关示例,请参阅 Git 仓库中的 examples/ 文件夹。

欢迎提出建议和批评!

// ...
use futures_retry::{RetryPolicy, StreamRetryExt};

// In this example we use a free function to handle errors, while in your project you have
// more options: for simple cases a simple closure will do, for complex cases you might go
// as far as implementing an `ErrorHandler` trait for a custom type with some complex logic.
fn handle_error(e: io::Error) -> RetryPolicy<io::Error> {
  match e.kind() {
    io::ErrorKind::Interrupted => RetryPolicy::Repeat,
    io::ErrorKind::PermissionDenied => RetryPolicy::ForwardError(e),
    _ => RetryPolicy::WaitRetry(Duration::from_millis(5)),
  }
}

async fn serve_connection(stream: TcpStream) {
  // ...
}

#[tokio::main]
async fn main() {
  let addr = //...
  # "127.0.0.1:12345";
  let mut listener = TcpListener::bind(addr).await.unwrap();
  let server = stream::try_unfold(listener, |listener| async move {
    Ok(Some((listener.accept().await?.0, listener)))
  })
  .retry(handle_error) // Magic happens here
  .and_then(|(stream, _attempt)| {
    tokio::spawn(serve_connection(stream));
    ok(())
  })
  .try_for_each(|_| ok(()))
  .map_err(|(e, _attempt)| eprintln!("Caught an error {}", e));
  # // This nasty hack is required to exit immediately when running the doc tests.
  # futures::pin_mut!(server);
  # let server = select(ok::<_, ()>(()), server).map(|_| ());
  server.await
}

许可证

许可协议为以下之一

任选其一。

贡献

除非您明确声明,否则您提交给工作的任何贡献,根据 Apache-2.0 许可证的定义,将根据上述许可证双重许可,不附加任何额外的条款或条件。

许可证:MIT/Apache-2.0

依赖项

~2.6–4MB
~61K SLoC