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 异步
4,819 每月下载量
用于 34 个 crate(29 个直接使用)
215KB
3K SLoC
tor-rtcompat
Arti 不同异步运行时的兼容性
概述
Rust 对异步编程的支持非常强大,但仍然不够成熟:您可以使用多个强大的运行时,但它们并没有提供一致的接口集。
futures
API 抽象了这些运行时库之间的许多差异,但仍然存在一些领域还没有标准 API,包括
- 网络编程。
- 时间和延迟。
- 启动新任务
- 阻塞直到任务完成。
此外,futures
提供的 AsyncRead
和 AsyncWrite
特性不同于 tokio
提供的,并且需要兼容包装器才能使用。
为了解决这些问题,tor-rtcompat
crate 提供了一组代表运行时执行这些任务的能力的特性和这些特性的实现,包括 tokio
和 async-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::Spawn
和Send
。
您可以通过几种方式获得一个Runtime
-
如果您已经有一个异步后端(例如,使用tokio构建的一个,通过运行
#[tokio::main]
创建的),您可以将其包装为一个Runtime
,使用PreferredRuntime::current()
。 -
如果您想要构建一个默认的运行时,您不会用它来执行除Arti之外的其他任何操作,您可以使用
PreferredRuntime::create()
。
上述两种方法都使用“首选运行时”,通常为Tokio。但是,可用的Cargo功能的集合可能会影响此设置;有关更多信息,请参阅PreferredRuntime
。
- 如果您想使用具有显式选择的后端的运行时,直接按其类型命名,例如
async_std::AsyncStdNativeTlsRuntime
,async_std::AsyncStdRustlsRuntime
,tokio::TokioNativeTlsRuntime
或tokio::TokioRustlsRuntime
。要构建这些运行时之一,调用其create()
方法。或者如果您已经构建了一个您想使用的 Tokio 运行时,您可以使用current()
明确将其包装为Runtime
。
高级使用:自己实现运行时
如果您在嵌入 Arti 并且想要对它使用的资源有更多控制权时,可能需要实现上述某些特性行为(特别是 TcpProvider
和 TlsProvider
)。例如,您可能希望在 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
软件包的一部分使用,其默认配置将启用 tokio
和 native-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