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
管理。