...
starcoin 异步模型分析
基于 actix
官方的 actix
首先应该先根据官方的文档,熟悉基本的 actix 框架,包括:actor,address,contex,arbiter 和 sync arbiter 这些基本概念。
...
RegistryService 比较特殊,它是第一个创建的 service,它的任务就是创建一个线程(用 actix 的 arbiter)其它 service,并把其它 service 放到它的 context 中缓存起来,而且它也存放了一些全局属性,比如 node config,vm config,甚至 gensis genesis 等对象。
主要有几个关键的功能:
函数名(同步)/消息(异步) | 作用与实现 |
---|---|
register/RegisterRequest | 创建一个线程,拉起一个 service |
register_by_factory(这是一个asyn 函数仅支持异步) | 同 register,但需要设计 service 方提供一个 factory类(实现ServiceFactory<S> 这个 trait,S 是 service 类) |
get_shared/GetShardRequest | 获取任何对象,一般是全局唯一的对象,比如配置,genesis,serivice 对象。里面用 any 存放 |
put_shared/PutShardRequest | 存放任何对象,一般是全局唯一的对象,比如配置,genesis,serivice 对象。里面用 any 存放 |
service_ref/ServiceRefRequest | 获得某个 service 的 ServiceRef,即 address |
这个 register serivice 的 address 会被放在 context 中,即每个 service 都可以引用它,给它发消息进行交互(异步使用),也可以同步调用它直接的实现函数(同步使用)。因此,RegistryService 相当于一个全局 service 容器,通过它(异步给它发消息 ServiceRefRequest<S>,同步直接调用 get_shared),可以获得其它 service 的 ServiceRef<S> 这样就可以和其它服务交互了。其关键代码见:commons/service-register/src/service_registry.rs。
...
await:一个 future 对象的特殊调用,即尝试执行一个 future,若 future 因为被挂起,则等待唤醒,唤醒后,继续往下执行。重点理解这篇文章:https://tokio.rs/tokio/tutorial/async 。简答的说,即:调用 await 会触发 future 类的 poll 调用,若 poll 函数返回 Ready 状态,那么 await 就返回,且带上 Ready 关联的返回值。若 poll 函数返回 Pending 状态,那么 await 继续挂起,即阻塞在 await 中,直到 有人调用 poll 中的 conntext waker 的 wake 函数,此时 poll 函数会重新被拉起,看 await 是否又可以继续执行:
(待补充图)
了解了基本的 future await 概念后就可以去看 futures的 stream 了。
...
stream 异步编程
Stream
futures 提供了一种特殊的异步模型,即 stream,它是基于 future 异步(注意 futures 和 future,前者是一个crate,后者是一个类)类实现的。
...