< 返回版块

[FAQ] Futures 和 Tokio 项目的前世今生

CrLF0710 发表于

用Rust搞网络相关,一般是绕不开这两个库的。这里尝试简单介绍一下它们的历史。

??~2016:原点

最初的时候。

首先futures是一套trait,也是异步操作的基本API。这个库是官方成员alexcrichton开发的。

然后是另一个叫做mio的库。mio是跨(桌面)平台的非阻塞IO API的封装,主要是 EventLoop实现(分别会使用epoll, kqueue, iocp)和其他一些Tcp、Udp的原语。这个库是carllerche开发的,他不是官方成员。但是这个项目是受到官方支持的。所以可以看作半官方项目。

好了,然后接下来就是futures和mio的整合了。因为futures只有trait,而mio是不依赖于futures的,所以需要一个库把它们整合在一起。这个库的名字叫futures_mio,是alexcrichton和carllerche两个人维护的。后来官方开始越来越重视这个,这个成为了官方支持的社区项目,可以看作是半官方项目,并把它列入到2017年的年度计划里,这是后话了。

2016~2017:Tokio 计划

2016年8月的时候,futures_mio 这个库也换了一个更响亮的名字,叫做tokio。tokio依赖futures和mio。tokio的计划是一整套异步支持的设施。这里面没有一个crate叫tokio。(tokio这个名字被预留了但是里面没有内容。)核心组件是tokio-core。并在上面有tokio-io, tokio-timer, tokio-proto等等。

tokio-core 里最重要的东西就是一个名叫Core的类型,它既是reactor又是executor。上层应用把用futures 接口表述的任务交给它,由它来调度执行。这是一个单线程的模型。在tokio-core的基础上,各种上层应用也纷纷尝试迁移过来获得异步支持,整个系统蓬勃地发展了起来。比如hyper(HTTP库),以及建筑在hyper之上的各种web框架。

试用了一段时间之后,大家一方面对它的本身的性能是满意的(参见几次techempower举办的 benchmark),另一方面在易用性上对tokio系统有很多不满意之处。首先它是那种基于回调的组合(参见使用老版本ES 的Nodejs),并且在调试的时候逻辑会跳来跳去。所以写起来,调试起来都不够好。其次,tokio-proto,这个tokio的上层设施(FramedCodec,Transport等),成为了彻底的鸡肋。

于是勤劳的alexcrichton又被安排以宏的形式实现了一个futures-await库,它可以让你标注一些async和await,以同步形式的代码来表述异步逻辑。这个大家应该都不陌生,其他语言很多也都有。【C++还没有,但是也快了。】实验进展的还是比较顺利的,不过这个必须要用nightly版本的rust编译器才能用。

积累了这些经验,在2017年末,官方又做了一个艰难的决定,搞了一个大新闻。

2017 Q4 ~2018 Q1

在2018年的分工里,勤劳的alexcrichton被安排去负责webassembly那一边了。futures这边的工作基本上移交给了官方新成立的net-wg小组。起到关键作用的是aturon和cramelj和withoutboats几位。

net组的工作重心从tokio转向了futures。然后做出了很多改动。

1. 首先是整个模型被重新设计了。tokio::Core 按照功能被解耦成了reactor和executor。于是在新的futures 里,futures 定义了 executor这个trait。
2. 为了解决之前不容易描述返回某种Future这个函数定义的麻烦,rust在这段时间内设计的impl Trait功能(也是alexcrichton提出来的!)派上了用场。
3. 然后为了处理生成的Future里含有自引用这种情况,withoutboats 设计了一套新的Pin API,能够在现有的规则下产生不能移动的类型,在很大程度上解决了这个问题。
4. 整合futures-await 到 futures 里面来。
5. futures开始提供executor和io的实现了,包括单线程调度器、线程池调度器等等。
6. tokio-proto被彻底放弃了。

于是在新的思路下。官方开始倡导:中立的futures 提供executor、io;tokio提供IO紧密相关的reactor和对外接口这样的设计。

同时在tokio这一边,carl等人并不完全认同官方的思路。tokio这边希望继续使用tokio自行设计实现的executor、io等接口,并且后续可能还会根据使用和反馈继续调整。设计和实现上由于可以有更多的耦合所以会更有针对性。

这里还是存在一些分歧和讨论。

What's coming next

日前(4月)官方提出了futures 0.3 计划。将futures里的futures-await部分整合进入语言里成为语言特性。为了达到这一点,官方也需要整合一小部分futures到标准库里。

目前这个计划的RFC已经提出来了。大家正在对RFC内容进行热烈的讨论。

评论区

作者 CrLF0710 2018-04-22T14:42:45.316371

对一整段经过的回顾,可能难免有疏漏之处,欢迎指正哈。

dispensable 2018-04-24T06:05:19.841711

辛苦了,算是对这有个大概的了解,还真是……不稳

作者 CrLF0710 2018-04-25T13:41:53.413889

4月25日更新最新进展:旧的"整合一小部分futures到标准库里" RFC被讨论否决,整合进语言的只有async/await机制,原futures-await整合进语言的只有解耦出来的async部分,使用名为Async的trait作为过渡。未来futures更成熟时仍有待定计划整合进入标准库。

Mike Tang 2018-04-27T03:41:00.117843

赞,很好的分析 。

FnA 2018-05-03T04:35:16.480289

辛苦了,赞一个,这么看来features这块还没有稳定下来,期待后面稳定下来,处理io这块性能肯定可以提升不少,官方工作人员也很辛苦呐。

龙三 2018-05-13T04:43:44.705928

好顶赞

1 共 6 评论, 共 1 页