Akka向设备组添加Actor注册《thirteen》译
我们已经完成了设备级别的注册支持,现在我们必须在组级别实现它。在注册时,小组成员还有更多工作要做,包括:
- 通过将注册请求转发给现有设备actor或通过创建新actor并转发消息来处理注册请求。
- 跟踪组中存在哪些设备Actor,并在组停止时从组中删除它们。
处理注册请求
设备组Actor必须将请求转发给现有子项,或者应创建一个。要通过设备ID查找子actor,我们将使用Map <String,ActorRef>。
我们还希望保留请求的原始发件人的ID,以便我们的设备角色可以直接回复。这可以通过使用forward而不是tell运算符来实现。两者之间的唯一区别是,forward会保留原始发件人,而tell会将发件人设置为当前的actor。就像我们的设备actor一样,我们确保不会响应错误的组ID。将以下内容添加到源文件中:
正如我们对设备所做的那样,我们测试了这个新功能。我们还测试了返回两个不同ID的Actor实际上是不同的,我们还尝试记录每个设备的温度读数,以查看Actor是否正在响应。
如果注册请求已存在设备actor,我们希望使用现有的actor而不是新的actor。我们还没有测试过,所以我们需要解决这个问题:
跟踪组中的设备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的功能实现:
到目前为止,我们无法获得组设备主体跟踪的设备,因此,我们无法测试我们的新功能。为了使其可测试,我们添加了一个新的查询功能(消息RequestDeviceList),列出了当前活动的设备ID:
我们几乎准备好测试设备的移除。但是,我们仍然需要以下功能:
- 从我们的测试用例中停止设备actor。从外面看,任何Actor都可以通过发送特殊的内置消息PoisonPill来停止,该消息指示Actor停止。
- 在设备actor停止后收到通知。我们也可以将Death Watch设施用于此目的。TestKit有两个我们可以轻松使用的消息,watch()来监视一个特定的actor,而expectTerminated断言被监视的actor已被终止。
我们现在再添加两个测试用例。首先,我们测试一旦添加了几个设备,我们就会返回正确的ID列表。第二个测试用例确保在设备actor停止后正确删除设备ID:
创建设备管理器角色
要进入层次结构中的下一个级别,我们需要在DeviceManager源文件中为设备管理器组件创建入口点。此actor与设备组actor非常相似,但是创建设备组actor而不是设备actor:
我们将设备管理器的测试留作练习,因为它与我们为组Actor编写的测试非常相似
What’s next?
我们现在有一个分层组件,用于注册和跟踪设备和记录测量。我们已经了解了如何实现不同类型的会话模式,例如:
- Request-respond(用于温度记录)
- Delegate-respond(用于设备注册)
- Create-watch-terminate(用于创建组和设备actor作为子项)
在下一章中,我们将介绍组查询功能,它将建立一个新的分散 - 聚集对话模式。特别是,我们将实现允许用户查询属于组的所有设备的状态的功能。
下节再续!
原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_4.html
有什么讨论的内容,可以加我公众号:
![](/img/my/wx.png)
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Play For Scala 开发指南 - 第10章 MongoDB 开发
为什么选择 MongoDB? 在Reactive越来越流行的今天,传统阻塞式的数据库驱动已经无法满足Reactive应用的需要了,为此我们将目光转向新诞生的数据库新星MongoDB。MongoDB 从诞生以来就争议不断,总结一下主要有以下几点: Schemaless 默认忽略错误 默认关闭认证 曾经的数据丢失问题 其实Schemaless和不支持事务是技术选型时的决定,不应该受到吐槽,主要看是否满足业务需求以及团队的喜好,没什么可争议的。至于默认忽略错误也是无稽之谈,对于那些非关键数据,MongoDB为你提供了一个Fire and Forget模式,可以显著提高系统性能,并且几乎所有的MongoDB驱动都默认关闭了这个模式,如果需要你可以手动打开。默认关闭认证并不是不支持认证,只是为了方便快速原型,如果你敢在线上裸奔MongoDB,我只能默默地为你点根蜡烛。数据丢失问题已经成为历史,曾经在网上广为流传的两篇关于MongoDB数据丢失问题(1,2), 经过分布式系统安全性测试组织JEPSEN最新的测试分析表明,MongoDB 3.4.0已经解决了这些问题。 聊完争议,我们来看看Mongo...
- 下一篇
认识 lib 目录里的 .so 文件
当我们安装了共享库并运行了 ldconfig 之后,通常我们会在 lib/ 里看到三个 .so 文件。这里的 so 是 shared object 之意。 libfoo.so.1.0.0 这是普通的(regular)共享库文件。可能有多个版本的该文件并存。 libfoo.so -> libfoo.so.1.0.0 这个符号链接一般用在程序的链接过程(link)。你向 linker 指定的参数 -lfoo 便是在寻找并链接 libfoo.so 这个文件。通常情况下这总是个指向具体动态库的符号链接,因为有可能你需要在不同版本的库间切换。 libfoo.so.1 -> libfoo.so.1.0.0 这个符号链接一般用在程序的运行时。每个 .so 都会有一个 SONAME。应用程序根据 SONAME 来寻找并加载共享库。libfoo.so.1 就是一个 SONAME。你可以通过 objdump -p libfoo.so.1.0.0 或 readelf -d libfoo.so.1.0.0 查看它。对于共享库的编写者来说,SONAME 相同的库应互相兼容。 有些包管理器(如 deb...
相关文章
文章评论
共有0条评论来说两句吧...