Telegram Actor Model
前文简要的分析了 TDLib 库提供的接口交互方式,接下来将说说它的参与者模式 tdactor。
如上图,Telegram 提供给上层应用调用的接口将从 Actor 对象 Td 进出。所有请求通过 request 发起,这得益于所有的结构数据都从 Function 派生通过请求参数即可识别请求方法。所有响应也将回调到 Td 上,然后交给 TdReceiver (这里没有画出来,见前文),当上层调用 receive 时从 TdReceiver 取出来。
注:
TdReceiver不是指 Actor 的 mailbox,它的 mailbox 存储在ActorInfo里,由Scheduler收件。
参与者
Telegram 中所有的交互都通过 Actor 来完成,应当从 Actor 类派生,对于它的信息存储在 ActorInfo 里,这里面最主要结构是 mailbox_,它将其它 Actor 发给它的调用按先后顺序存储起来,也就是对于其它 Actor 发过来的消息是不会并发调用的,它们单线程模式逐个执行。
上图中的 ServiceActor 是个特殊的 Actor,主要目的是不让 Scheduler 没有事件要处理时可以休眠,事件到达时可以唤醒,以及将消息发送到在其它 Scheduler 的 Actor 时,对方可以通过它接收 Event。
另外一个值得注意的是,Actor 驻留在特定的 Schedule 上以单线程的形式执行,当然它也可以在不同的 Scheduler 迁移,只是只能有一个宿主。
邮箱
Actor 之间通过 Event 进行交互,也就我们通常编程一个对象调用另一个对象的方法时,我们也可以打包成一个函数对象,这里也类似,它将这个函数对象存储到一个 Event 里,使得不同的函数对象具有相同的基类,以便可以存储到容器中。当一个 Actor 给另一个 Actor 发消息时,其实就是通过 Scheduler 把 Event 放到它的 ActorInfo 的 mailbox 中。
调度器
前面说到每个 Actor 都有一个宿主 Scheduler,它是单线程的,这个调度器用于完成 Event 的发送和接收,以及当接收消息的 Actor 不在同一个 Scheduler 时的迁移动作。为了实现多线程,需要定义多个 Scheduler 协同工作,由 ConcurrentScheduler 管理。