Rust高效率异步I/O模型

              
banq 16-08-13

Rust生态系统已经提供快速产品化的异步I/O模型,但是过于低级,需要自己状态机与回调函数。现在零消耗future模型开源项目:https://github.com/alexcrichton/futures-rs发布了,该模型是高层次抽象,能够进行组合,其实它类似于很多语言中的future模型或promise模型,主要加入一些async/await语法糖。

所谓零消耗抽象,也就是说,不会因为提高抽象层次导致过多冗余代码,这个高层次抽象编译后等同于状态机+回调函数,没有过多其他辅助代码,从而保证了高层次代码与低层次代码同样的执行效率。

异步future模型可以实现一些任务:
1.数据库查询
这是在线程池中执行,当查询完成后,future完成了,它的值就是查询结果。

2.RPC调用服务器,当服务器响应后,future完成了,它的值就是服务器响应

3.计时,当计时时间到,future完成,它的值就是计时完成返回函数

4.长时间CPU密集任务,运行在线程池,当任务完成时,future也完成,值就是任务返回值。

5.从socket读取字节,当字节准备好后,future已经完成了,依赖缓冲策略,直接返回字节。

Rust是将future作为一个trait接口:

trait Future {
type Item;
// ... lots more elided ...
}


下面是几种不同future实现:

// 根据id查询表一行记录,当完成查询后yield返回该行
fn get_row(id: i32) -> impl Future<Item = Row>;

// 进行RPC 调用,yield返回i32
fn id_rpc(server: &RpcServer) -> impl Future<Item = i32>;

// 向TCP流写入整个字符串,当完成后yielding返回这个流。
fn write_string(socket: TcpStream, data: String) -> impl Future<Item = TcpStream>;


此外还可以使用future完成:Sequential组合;mapping;joining和selecting

使用future可以进行流处理组合:

// 对于输入I/O 对象创建一个请求流
let requests = ParseStream::new(input);

// 对于每个请求,运行服务的`process`函数处理请求产生响应
let responses = requests.and_then(|req|service.process(req));

//创建新的future 将会把每个响应输出到 I/O对象
StreamWriter::new(responses, output)


为了验证零消耗抽象的future模型的高性能,使用该模型编写的简单 minihttp服务器与流行的最快几个服务器框架比较,包括:
1.rapidoid:这是一个java框架,上一轮是最高性能
2.Go语言,使用标准HTTP库包
3.fasthttp是Go的标准HTTP竞争者
4.Node.js

性能从高到低结果是:minihttp(Rust)、rapidoid(Java)、fasthttp(Go)、Go和node.js.



原文:
Zero-cost futures in Rust · Aaron Turon