Akka向设备组添加Actor注册《thirteen》译
我们已经完成了设备级别的注册支持,现在我们必须在组级别实现它。在注册时,小组成员还有更多工作要做,包括:
- 通过将注册请求转发给现有设备actor或通过创建新actor并转发消息来处理注册请求。
- 跟踪组中存在哪些设备Actor,并在组停止时从组中删除它们。
处理注册请求
设备组Actor必须将请求转发给现有子项,或者应创建一个。要通过设备ID查找子actor,我们将使用Map <String,ActorRef>。
我们还希望保留请求的原始发件人的ID,以便我们的设备角色可以直接回复。这可以通过使用forward而不是tell运算符来实现。两者之间的唯一区别是,forward会保留原始发件人,而tell会将发件人设置为当前的actor。就像我们的设备actor一样,我们确保不会响应错误的组ID。将以下内容添加到源文件中:
Full source at GitHub
正如我们对设备所做的那样,我们测试了这个新功能。我们还测试了返回两个不同ID的Actor实际上是不同的,我们还尝试记录每个设备的温度读数,以查看Actor是否正在响应。
Full source at GitHub
如果注册请求已存在设备actor,我们希望使用现有的actor而不是新的actor。我们还没有测试过,所以我们需要解决这个问题:
Full source at GitHub
跟踪组中的设备Actor
到目前为止,我们已经实现了在组中注册设备actor的逻辑。然而,设备来来去去,所以我们需要一种从Map <String,ActorRef>中删除设备actor的方法。我们将假设当移除设备时,其相应的设备actor将停止。正如我们前面讨论的那样,监督只处理错误情况 - 不是优雅的停止。因此,我们需要在其中一个设备actor停止时通知父级。
Akka提供死亡观察功能,允许Actor观看另一个Actor,并在其他Actor停止时收到通知。与监督不同,观看不仅限于父子关系,任何Actor都可以观看任何其他Actor,只要它知道ActorRef即可。在观看的Actor停止之后,观察者接收终止(actorRef)消息,该消息还包含对观看的Actor的引用。观察者可以显式处理此消息,也可以使用DeathPactException失败。如果Actor在观看Actor停止后不再履行自己的职责,后者就很有用。在我们的例子中,该组在一个设备停止后仍然应该起作用,因此我们需要处理Terminated(actorRef)消息。
我们的设备组Actor需要包含以下功能:
- 在创建新设备Actor时开始观察它们。
- 当通知指示已停止时,从Map <String,ActorRef>中删除设备actor,该设备actor将设备映射到设备actor。
不幸的是,Terminated消息只包含子actor的ActorRef。我们需要actor的ID将其从现有设备的映射中移除到设备actor映射。为了能够执行此删除,我们需要引入另一个占位符Map <ActorRef,String>,它允许我们找出与给定ActorRef对应的设备ID。
添加识别actor的功能实现:
Full source at GitHub
到目前为止,我们无法获得组设备主体跟踪的设备,因此,我们无法测试我们的新功能。为了使其可测试,我们添加了一个新的查询功能(消息RequestDeviceList),列出了当前活动的设备ID:
Full source at GitHub
我们几乎准备好测试设备的移除。但是,我们仍然需要以下功能:
- 从我们的测试用例中停止设备actor。从外面看,任何Actor都可以通过发送特殊的内置消息PoisonPill来停止,该消息指示Actor停止。
- 在设备actor停止后收到通知。我们也可以将Death Watch设施用于此目的。TestKit有两个我们可以轻松使用的消息,watch()来监视一个特定的actor,而expectTerminated断言被监视的actor已被终止。
我们现在再添加两个测试用例。首先,我们测试一旦添加了几个设备,我们就会返回正确的ID列表。第二个测试用例确保在设备actor停止后正确删除设备ID:
Full source at GitHub
创建设备管理器角色
要进入层次结构中的下一个级别,我们需要在DeviceManager源文件中为设备管理器组件创建入口点。此actor与设备组actor非常相似,但是创建设备组actor而不是设备actor:
Full source at GitHub
我们将设备管理器的测试留作练习,因为它与我们为组Actor编写的测试非常相似
What’s next?
我们现在有一个分层组件,用于注册和跟踪设备和记录测量。我们已经了解了如何实现不同类型的会话模式,例如:
- Request-respond(用于温度记录)
- Delegate-respond(用于设备注册)
- Create-watch-terminate(用于创建组和设备actor作为子项)