当前位置: 首页 > news >正文

rust-tokio发布考古

源头: Carl Lerche  Aug 4, 2016

​ I’m very excited to announce a project that has been a long time in the making.
我很兴奋地宣布一个酝酿已久的项目。

Tokio is a network application framework for rapid development and highly scalable deployments of clients and servers in the Rust programming language. ​

Tokio 是一个网络应用框架,用于Rust编程语言中客户端和服务器的快速开发和高度可扩展的部署。

It strives to make writing robust, scalable, and production ready network clients and servers as easy as possible. It does this by focusing on small and reusable components… and by being really, really, fast.

它致力于尽可能轻松地编写健壮、可扩展且可用于生产的网络客户端和服务器。 它通过专注于小型且可重复使用的组件来实现这一点……并且非常非常快。

GitHub - tokio-rs/tokio: A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

Let’s start our tour of Tokio.
让我们开始我们的Tokio之旅。

Service Trait 服务特点

​Writing composable and reusable components is made possible by standardizing the interface that clients and servers use. In Tokio, this standardized interface is the `Service` trait and it is the cornerstone of Tokio’s building blocks. This trait is heavily inspired (Ok, stolen) from Finagle. ​
通过标准化客户端和服务器使用的接口,可编写可组合和可重用的组件。 在 Tokio 中,这个标准化接口是“Service”特征,它是 Tokio 构建块的基石。 这个特性很大程度上受到 Finagle 的启发(好吧,是偷来的)。

Here is what the Service trait looks like:
下面是Service trait的样子:

pub trait Service: Send + 'static {type Req: Send + 'static;type Resp: Send + 'static;type Error: Send + 'static;type Fut: Future<Item = Self::Resp, Error = Self::Error>;fn call(&self, req: Self::Req) -> Self::Fut;
}

A relatively simple trait, but it unlocks a world of possibility. This symmetric and uniform API reduces your server or client into a function, thus enabling middleware (or filters, depending on your lingo).

这是一个相对简单的特征,但它开启了一个充满可能性的世界。 这种对称且统一的 API 将您的服务器或客户端简化为一个函数,从而启用中间件(或过滤器,具体取决于您的常用术语)。

A Service is an asynchronous function from Request to Response, where asynchronicity is managed by the brilliant Futures crate.
服务是从请求到响应的异步功能,其中的异步性由出色的Futures crate管理。

A middleware is a component that acts both as a client and a server. It intercepts a request, modifies it, and passes it on to an upstream Service value.

中间件是一个既当客户端又当服务器的组件。 它拦截请求,修改请求,并将其传递给上游Service值。

Let us use timeouts as an example, something every network application requires.
让我们以超时为例,这是每个网络应用程序都需要的。

pub struct Timeout<T> {upstream: T,delay: Duration,timer: Timer,
}impl<T> Timeout<T> {pub fn new(upstream: T, delay: Duration) -> Timeout<T> {Timeout {upstream: upstream,delay: delay,timer: Timer::default(),}}
}impl<T> Service for Timeout<T>where T: Service,T::Error: From<Expired>,
{type Req = T::Req;type Resp = T::Resp;type Error = T::Error;type Fut = Box<Future<Item = Self::Resp, Error = Self::Error>>;fn call(&self, req: Self::Req) -> Self::Fut {// Get a future representing the timeout and map it to the Service error typelet timeout = self.timer.timeout(self.delay).and_then(|timeout| Err(Self::Error::from(timeout)));// Call the upstream service, passing along the requestself.upstream.call(req)// Wait for either the upstream response or the timeout to happen.select(timeout)// Map the result of the select back to the expected Response type.map(|(v, _)| v).map_err(|(e, _)| e).boxed()}
}

This Timeout middleware, shown above, only has to be written once, then it can be inserted as part of any network client for any protocol, as shown below.

如上所示,这个超时中间件只需编写一次,然后它就可以作为任何协议的任何网络客户端的一部分插入,如下所示。

let client = Timeout::new(http::Client::new(),Duration::from_secs(60));client.call(http::Request::get("https://www.rust-lang.org")).and_then(|response| {// Process the responseOk(())}).forget(); // Process the future

Now, the really interesting thing is that the exact same middleware could be used in a server as well, shown below.
现在,真正有趣的事情是,完全相同的中间件也可以在服务器中使用,如下所示。

http::Server::new().serve(Timeout::new(MyService, Duration::from_secs(60)));

Tokio’s Reactor Tokio’s 的Reactor 

The Service trait addresses how all the various network services fit together to build one cohesive application, but it doesn’t care about the details of how each service is built. This is where the Tokio reactor fits in.
Service trait解决了如何将各种网络服务组合在一起以构建一个高内聚应用程序的问题,但它并不关心每个服务是如何构建的细节。这就是Tokio reactor的用武之地。

The Tokio reactor is a non-blocking runtime built on top of Mio. It has the job of scheduling tasks to run based on readiness notifications of the underlying sockets.
Tokio Reactor 是构建在 Mio 之上的非阻塞运行时。 它的任务是根据底层socket的就绪通知来调度任务运行。

Let us start with a simple example: listening on a socket and accepting inbound connections.
让我们从一个简单的例子开始:监听socket并接受入站连接。

struct Listener {socket: TcpListener,
}impl Task for Listener {fn tick(&mut self) -> io::Result<Tick> {// As long as there are sockets to accept, accept and process themwhile let Some(socket) = try!(self.socket.accept()) {// Do something with the socket}Ok(Tick::WouldBlock)}
}pub fn main() {let reactor = Reactor::default().unwrap();// Run a closure on the reactorreactor.handle().oneshot(|| {let addr = "0.0.0.0:0".parse().unwrap();let listener = try!(TcpListener::bind(&addr));// Schedule the task managing the listenerreactor::schedule(Listener { socket: listener });Ok(())});reactor.run();
}

Look at all the things that I’m not doing. This is all non-blocking code. There is no interest explicitly registered with the reactor, there are no callbacks passed around, everything happens right there in the `tick` function.

看看我没有做的所有事情,这都是非阻塞代码。 没有向reactor显式登记注册,没有回调传递,一切都发生在“tick”函数中。

This is where I think Tokio does something new and interesting (if this has been done before, I am not aware of it).
这就是我认为Tokio 做了一些新的有趣的事情的地方(如果这是以前做过的,我不知道)。

Instead of requiring that you explicitly register interest in a socket in order to receive readiness notifications, as Mio requires, Tokio observes which sources (in this case, a TcpListener) the task depends on by noticing which sources the task uses. In other words, by simply using your sockets, timers, channels, etc… you are expressing readiness interest to the reactor.
Mio要求您显式地注册对socket 的兴趣以接收就绪通知,而不是像Mio那样,Tokio 通过注意任务使用的哪些源来观察任务所依赖的源(在本例中是TcpListener)。换句话说,通过简单地使用你的sockets,计时器,通道等..

So, in this example, the first time the reactor calls the Listener task, `self.socket.accept()` will return `Ok(None)` which indicates that the listener socket is not ready to complete the accept operation. However, the listener socket will also register interest in itself with the reactor. When the listener becomes ready, the task is invoked again by the reactor. This time the accept will succeed. The reactor is able to make its observations with virtually no performance overhead. You can see for yourself if you don’t believe me. ​

因此,在这个例子中,反应器第一次调用监听器任务时,“self.socket.accept()”将返回“Ok(None)”,这表明listener socket尚未准备好完成接受操作。 然而,listener socket也会向reactor注册登记。 当listener准备就绪时,reactor将再次调用该任务。 这次accept就成功了。

该reactor能够在几乎没有任何性能开销的情况下进行观测。 如果您不相信我,您可以亲自看看。

​ This pattern works out nicely for more complex cases as well. I’m looking forward to seeing what people come up with. ​
这种模式也适用于更复杂的情况。我很期待看到人们想出什么。

Community 社区

Tokio is now open to the world while still at a very early stage. This is intentional. Release early, release often. I am hoping to get the Rust community involved now to shape the direction of Tokio and to get the protocol & middleware ecosystem jump started. It is up to you to build these reusable components and share them.
Tokio 现在向世界开放,但仍处于非常早期的阶段。这是故意的。尽早发布,经常发布。我希望现在就让 Rust 社区参与进来,以塑造 Tokio 的方向,并让协议和中间件生态系统快速启动。 您可以构建这些可重用组件并共享它们。

Do you want a Cassandra driver? Write it. Do you want an HTTP 2 server? Do it!
你想要一个Cassandra 数据库驱动程序吗?开始写吧。你想要一个HTTP 2服务器吗?动手吧!

A number of Rust community members have already jumped in to help shape Tokio to what it is today.
一些Rust社区成员已经加入进来,帮助时雄塑造今天的样子​ 。

Sean McArthur of Hyper has already started working to integrate the Tokio reactor in Hyper for the 0.10 release. His feedback has been invaluable. We already have a proof of concept HTTP server providing a Service trait based API. ​
Hyper 的 Sean McArthur 已经开始致力于将 Tokio Reactor 集成到 Hyper 0.10 版本中。他的反馈是无价的。我们已经有了一个概念验证 HTTP 服务器,提供基于服务特征的 API​ 。 ​

Tikue is working on getting his RPC framework Tarpc working on Tokio using the provided building blocks. We’ve already discovered further components Tokio could provide to reduce the amount of time he has to spend writing networking code. ​

Tikue 正在致力于使用提供的构建块让他的 RPC 框架 Tarpc 在 Tokio 上运行。 我们已经发现 Tokio 可以提供更多组件来减少他编写网络代码所需的时间。 ​

This is the beginning, not the end. There is still so much to do and I hope that we can all do it together. If you want to build something with Tokio, get involved. Talk to me and the other members of the Tokio community.  Let’s build this together.

这是开始,而不是结束。 还有很多事情要做,我希望我们大家能够一起完成。 如果您想与 Tokio 一起构建一些东西,请参与其中。 与我和 Tokio 社区的其他成员交谈。 让我们一起构建这个。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 少儿编程 2024年3月电子学会图形化编程等级考试Scratch二级真题解析(判断题)
  • 函数重载和引用【C++】
  • Unity类银河恶魔城学习记录12-7-2 p129 Craft UI - part 2源代码
  • git lfs如何使用
  • AI-漫画推文
  • 二维数组及其内存图解
  • 云手机提供私域流量变现方案
  • 如何在Java中创建对象输入流
  • WPF Pack
  • C# 字符串和枚举类型互相转换
  • 007 spring aop(通知)(xml)
  • fastlio2 保存每帧的点云和每帧的里程计为单独的文件做后端回环优化和手动回环优化
  • 整数和(推公式)
  • MongoDB复制集安装配置图文教程-Windows篇 fasstgpt必看
  • Rust---复合数据类型之字符串与切片(2)
  • 30秒的PHP代码片段(1)数组 - Array
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • HTTP中的ETag在移动客户端的应用
  • Linux链接文件
  • Linux下的乱码问题
  • Mithril.js 入门介绍
  • Octave 入门
  • orm2 中文文档 3.1 模型属性
  • Selenium实战教程系列(二)---元素定位
  • Webpack入门之遇到的那些坑,系列示例Demo
  • Yeoman_Bower_Grunt
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 从setTimeout-setInterval看JS线程
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 力扣(LeetCode)22
  • 前端_面试
  • 前端自动化解决方案
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 入手阿里云新服务器的部署NODE
  • 第二十章:异步和文件I/O.(二十三)
  • ​ArcGIS Pro 如何批量删除字段
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • #mysql 8.0 踩坑日记
  • (0)Nginx 功能特性
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (二)斐波那契Fabonacci函数
  • (二)原生js案例之数码时钟计时
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)http协议
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .NET应用UI框架DevExpress XAF v24.1 - 可用性进一步增强
  • .pub是什么文件_Rust 模块和文件 - 「译」