29 个版本 (15 个重大更改)

0.21.0 2024 年 8 月 1 日
0.20.0 2024 年 6 月 27 日
0.19.0 2024 年 6 月 5 日
0.10.0 2024 年 2 月 5 日
0.0.0 2021 年 6 月 24 日

#82 in 异步

Download history 630/week @ 2024-04-28 400/week @ 2024-05-05 220/week @ 2024-05-12 585/week @ 2024-05-19 788/week @ 2024-05-26 537/week @ 2024-06-02 716/week @ 2024-06-09 1543/week @ 2024-06-16 1183/week @ 2024-06-23 1613/week @ 2024-06-30 253/week @ 2024-07-07 551/week @ 2024-07-14 728/week @ 2024-07-21 1514/week @ 2024-07-28 1417/week @ 2024-08-04 1047/week @ 2024-08-11

4,819 每月下载量
用于 34 个 crate(29 个直接使用)

MIT/Apache

215KB
3K SLoC

tor-rtcompat

Arti 不同异步运行时的兼容性

概述

Rust 对异步编程的支持非常强大,但仍然不够成熟:您可以使用多个强大的运行时,但它们并没有提供一致的接口集。

futures API 抽象了这些运行时库之间的许多差异,但仍然存在一些领域还没有标准 API,包括

  • 网络编程。
  • 时间和延迟。
  • 启动新任务
  • 阻塞直到任务完成。

此外,futures 提供的 AsyncReadAsyncWrite 特性不同于 tokio 提供的,并且需要兼容包装器才能使用。

为了解决这些问题,tor-rtcompat crate 提供了一组代表运行时执行这些任务的能力的特性和这些特性的实现,包括 tokioasync-std 运行时。未来我们希望根据需要添加对其他运行时的支持。

这个 crate 是 Arti 的一部分,Arti 是一个用 Rust 实现 Tor 的项目。因此,它目前不包括(或计划包括)任何 Arti 实现 Tor 所需之外的功能。

我们希望在未来,这个crate可以被标准化和通用版本的特质所取代(或大部分取代)。

使用 tor-rtcompat

tor-rtcompat crate提供了几个特质,这些特质封装了不同的运行时能力。

  • 如果一个运行时可以阻塞在future上,那么它就是一个BlockOn
  • 如果一个运行时可以创建定时future,这些future在给定的时间间隔后变为Ready,那么它就是一个SleepProvider
  • 如果一个运行时提供了一种快速查询的单调时钟,但可能精度或准确度较低,那么它就是一个CoarseTimeProvider
  • 如果一个运行时可以创建和接收TCP连接,那么它就是一个TcpProvider
  • 如果一个运行时可以创建TLS连接,那么它就是一个TlsProvider

为了方便,Runtime特质从上述所有特质中继承,还包括futures::task::SpawnSend

您可以通过几种方式获得一个Runtime

  • 如果您已经有一个异步后端(例如,使用tokio构建的一个,通过运行#[tokio::main]创建的),您可以将其包装为一个Runtime,使用PreferredRuntime::current()

  • 如果您想要构建一个默认的运行时,您不会用它来执行除Arti之外的其他任何操作,您可以使用PreferredRuntime::create()

上述两种方法都使用“首选运行时”,通常为Tokio。但是,可用的Cargo功能的集合可能会影响此设置;有关更多信息,请参阅PreferredRuntime

高级使用:自己实现运行时

如果您在嵌入 Arti 并且想要对它使用的资源有更多控制权时,可能需要实现上述某些特性行为(特别是 TcpProviderTlsProvider)。例如,您可能希望在 TCP 连接打开和关闭时执行某些操作,用您自己的替换 TLS 堆栈,或通过您自己的自定义传输代理 TCP 连接。

这可以通过使用 CompoundRuntime 类型更容易实现,它允许您从各种特性行为的实现者创建 Runtime(这些实现者不需要都是相同的)。

请参阅 arti-client/examples/hook-tcp.rs 以获取此功能的完整示例。

Cargo 功能

此软件包支持的功能

  • tokio -- 带有 Tokio 支持构建
  • async-std -- 带有 async-std 支持构建
  • native-tls -- 带有 native-tls 软件包的 TLS 支持构建
  • static -- 静态链接本地 TLS 库(启用 native-tls 软件包的 vendored 功能)。
  • rustls -- 带有 rustls 软件包的 TLS 支持构建。请注意,rustls 使用 ring 软件包,它使用旧的(3BSD/SSLEay)OpenSSL 许可证,这可能会引入许可兼容性问题。

默认情况下, 软件包不启用任何功能。然而,您几乎肯定是将此作为 arti-client 软件包的一部分使用,其默认配置将启用 tokionative-tls

设计常见问题解答

为什么支持 async_std

尽管 Tokio 目前比 async_std 更受欢迎且支持更广泛,但我们认为针对多个运行时构建 Arti 是至关重要的。

通过支持多个运行时,我们避免在代码中做出针对 tokio 的特定假设,这希望将来更容易移植到其他环境(如 WASM)。

为什么是 Runtime 特性,而不是一组函数?

我们可以通过删除大部分暴露的特性来显著简化这段代码,而只暴露一个实现。例如,我们可以提供一个全局的 block_on 函数来代替暴露一个表示任务完成的阻塞的 BlockOn 特性。

然而,这种简化会付出一定的代价。首先,这将使正确使用 Rust 的“功能”系统变得更加困难。当前的功能应该是 仅可添加 的,但如果有一个全局运行时,则对不同后端的支持将是 互斥的。(也就是说,不能同时构建 tokio 和 async-std 功能。)

其次,Arti 其余部分的测试很大程度上依赖于替换 Runtime 的能力。通过将运行时视为一个对象,我们可以覆盖运行时对时间或网络的视图,以有效地测试异步代码。(请参阅 tor-rtmock 集成以获取示例。)

许可证:MIT OR Apache-2.0

依赖关系

~4–23MB
~324K SLoC