Telegram Actor Model

前文简要的分析了 TDLib 库提供的接口交互方式,接下来将说说它的参与者模式 tdactor

TDLib Actor

如上图,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 没有事件要处理时可以休眠,事件到达时可以唤醒,以及将消息发送到在其它 SchedulerActor 时,对方可以通过它接收 Event

另外一个值得注意的是,Actor 驻留在特定的 Schedule 上以单线程的形式执行,当然它也可以在不同的 Scheduler 迁移,只是只能有一个宿主。

邮箱

Actor 之间通过 Event 进行交互,也就我们通常编程一个对象调用另一个对象的方法时,我们也可以打包成一个函数对象,这里也类似,它将这个函数对象存储到一个 Event 里,使得不同的函数对象具有相同的基类,以便可以存储到容器中。当一个 Actor 给另一个 Actor 发消息时,其实就是通过 SchedulerEvent 放到它的 ActorInfomailbox 中。

调度器

前面说到每个 Actor 都有一个宿主 Scheduler,它是单线程的,这个调度器用于完成 Event 的发送和接收,以及当接收消息的 Actor 不在同一个 Scheduler 时的迁移动作。为了实现多线程,需要定义多个 Scheduler 协同工作,由 ConcurrentScheduler 管理。