当我们说Actor生命周期的时候,我们能看到Actor能被很多种方式停掉(用ActorSystem.stop或ActorContext.stop或发送一个PoisonPill - 也有一个killgracefulstop)。

无论Actor是怎么死的,有些情况一些系统中的其他actor想要知道。让我们举一个Actor与数据库交互的例子 - 我们叫它RepositoryActor。很明显,会有一些其他actor会向这个RepositoryActor发送消息。这些有“兴趣”的Actor很愿意留个eye或者看(watch)这个actor关闭时的消息。这个在Actor里面叫DeathWatch。这个用来watchunwatch的方法就是ActorContext.watchActorContext.unwatch。如果已经监视了,这些watcher会在Actor关闭时收到一个Terminated消息,并可以很舒服的加到他们的receive功能中。

不像Supervision有一个严格的父子继承关系,任何Actor都可以watch任何ActorSystem中的Actor。

让我们看下。

代码

QUOTEREPOSITORYACTOR

1.我们的QueryRepositoryActor格言查询Actor保存了一个quote的列表并且在收到一个QuoteRepositoryRequest时随机返回一条。

  1. 他记录了收到消息的个数,如果收到超过3个消息,他用PoisonPill把自己杀掉

这没啥神奇的。

package me.rerun.akkanotes.deathwatchimport akka.actor.{PoisonPill, Actor, ActorLogging, actorRef2Scala}
import me.rerun.akkanotes.protocols.QuoteRepositoryProtocol._
import scala.util.Randomclass QuoteRepositoryActor() extends Actor with ActorLogging {val quotes = List("Moderation is for cowards","Anything worth doing is worth overdoing","The trouble is you think you have time","You never gonna know if you never even try")var repoRequestCount:Int=1def receive = {case QuoteRepositoryRequest => {if (repoRequestCount>3){self!PoisonPill}else {//Get a random Quote from the list and construct a responseval quoteResponse = QuoteRepositoryResponse(quotes(Random.nextInt(quotes.size)))log.info(s"QuoteRequest received in QuoteRepositoryActor. Sending response to Teacher Actor $quoteResponse")repoRequestCount=repoRequestCount+1sender ! quoteResponse}}}}

TEACHERACTORWATCHER

一样的,TeacherActorWatcher也没啥神奇的,除了他创建了一个QuoteRepositoryActor并且用context.watch观察。

package me.rerun.akkanotes.deathwatchimport akka.actor.{Terminated, Props, Actor, ActorLogging}
import me.rerun.akkanotes.protocols.TeacherProtocol.QuoteRequest
import me.rerun.akkanotes.protocols.QuoteRepositoryProtocol.QuoteRepositoryRequestclass TeacherActorWatcher extends Actor with ActorLogging {val quoteRepositoryActor=context.actorOf(Props[QuoteRepositoryActor], "quoteRepositoryActor")context.watch(quoteRepositoryActor)def receive = {case QuoteRequest => {quoteRepositoryActor ! QuoteRepositoryRequest}case Terminated(terminatedActorRef)=>{log.error(s"Child Actor {$terminatedActorRef} Terminated")}}
}

测试CASE

这里会有点意思。我从来没想过这个可以被测试。akka-testkit。我们会分析下这三个测试CASE:

1. 断言如果观察到已经收到Terminated消息

QuoteRepositoryActor应该在收到第四条消息时给测试case发送一条Terminated消息。前三条应该是可以的。

"A QuoteRepositoryActor" must {........."send back a termination message to the watcher on 4th message" in {val quoteRepository=TestActorRef[QuoteRepositoryActor]val testProbe=TestProbe()testProbe.watch(quoteRepository) //Let's watch the Actorwithin (1000 millis) {var receivedQuotes = List[String]()(1 to 3).foreach(_ => quoteRepository ! QuoteRepositoryRequest)receiveWhile() {case QuoteRepositoryResponse(quoteString) => {receivedQuotes = receivedQuotes :+ quoteString}}receivedQuotes.size must be (3)println(s"receiveCount ${receivedQuotes.size}")//4th messagequoteRepository!QuoteRepositoryRequesttestProbe.expectTerminated(quoteRepository)  //Expect a Terminated Message}}

2.如果没有观察(watched/unwatched)到则断言没收到Terminated消息

事实上,我们做这个只是演示下context.unwatch。如果我们移掉testProbe.watch和testProbe.unwatch这行,则测试case会运行的很正常。

    "not send back a termination message on 4th message if not watched" in {val quoteRepository=TestActorRef[QuoteRepositoryActor]val testProbe=TestProbe()testProbe.watch(quoteRepository) //watchingwithin (1000 millis) {var receivedQuotes = List[String]()(1 to 3).foreach(_ => quoteRepository ! QuoteRepositoryRequest)receiveWhile() {case QuoteRepositoryResponse(quoteString) => {receivedQuotes = receivedQuotes :+ quoteString}}testProbe.unwatch(quoteRepository) //not watching anymorereceivedQuotes.size must be (3)println(s"receiveCount ${receivedQuotes.size}")//4th messagequoteRepository!QuoteRepositoryRequesttestProbe.expectNoMsg() //Not Watching. No Terminated Message}}

3. 在TeacherActorWatcher中断言收到了Terminated消息

我们订阅了EventStream并通过检查一个特殊的日志消息来断言termination。

   "end back a termination message to the watcher on 4th message to the TeacherActor" in {//This just subscribes to the EventFilter for messages. We have asserted all that we need against the QuoteRepositoryActor in the previous testcaseval teacherActor=TestActorRef[TeacherActorWatcher]within (1000 millis) {(1 to 3).foreach (_=>teacherActor!QuoteRequest) //this sends a message to the QuoteRepositoryActorEventFilter.error (pattern="""Child Actor .* Terminated""", occurrences = 1).intercept{teacherActor!QuoteRequest //Send the dangerous 4th message}}}

EventFilter中的pattern属性,没啥奇怪的,需要一个正则表达式。正则pattern=”“”Child Actor .* Terminated”“”用来匹配一条格式是Child Actor {Actor[akka://TestUniversityMessageSystem/user/$$d/quoteRepositoryActor#-1905987636]} Terminated日志信息。

Github

与往常一样,代码在github。看下deathwatch的包。


文章来自微信平台「麦芽面包」(微信扫描二维码关注)。未经允许,禁止转载。

[翻译]AKKA笔记 - DEATHWATCH -7相关推荐

  1. [翻译]AKKA笔记 - CHILD ACTORS与ACTORPATH -6

    原文:http://rerun.me/2014/10/21/akka-notes-child-actors-and-path/ Actor是完全的继承结构.你创建的任何Actor肯定都是一个其他Act ...

  2. [翻译] AKKA笔记- ACTORSYSTEM (配置CONFIGURATION 与调度SCHEDULING) - 4(二)

    原文地址 http://rerun.me/2014/10/06/akka-notes-actorsystem-in-progress/ 2. SCHEDULE 可以看到在ActorSystem的API ...

  3. 增量式分级判别回归树(IHDR)|翻译与笔记

    增量式分级判别回归树(IHDR)|翻译与笔记 为什么翻译这篇发表于2007年的老论文呢?主要有以下四方面原因: (1)这篇论文较清晰地给出增量式学习的概念. (2)论文有一定的理论与应用方面的价值. ...

  4. 联邦学习笔记-《Federated Machine Learning: Concept and Applications》论文翻译个人笔记

    联邦学习笔记-<Federated Machine Learning: Concept and Applications>论文翻译个人笔记 摘要 今天的人工智能仍然面临着两大挑战.一是在大 ...

  5. [木野狐]ViewState 剖析(翻译兼笔记)

    [木野狐]ViewState 剖析(翻译兼笔记) 原文链接:ViewState: All You Wanted to Know 作者:Paul Wilson翻译:木野狐 ViewState 不是什么? ...

  6. A Survey of Deep Learning-based Object Detection论文翻译 + 阅读笔记

    A Survey of Deep Learning-based Object Detection论文翻译 + 阅读笔记 //2022.1.7 日下午16:00开始阅读 双阶段检测器示意图 单阶段检测器 ...

  7. 干货分享:高效办公工具【视频转文字、视频播放器、B站视频下载软件、贴图、截图提取文字并翻译、笔记记录软件、任务管理网站】

    高效办公工具分享--视频转文字.视频播放器.B站视频下载软件.贴图.截图提取文字并翻译.笔记记录软件.任务管理网站 一 前言 二.下载链接及效果 1.视频自动转文字-飞书妙记(目前免费使用!!) 2. ...

  8. 区块链分片:《Monoxide: Scale Out Blockchain with Asynchronous Consensus Zones》论文翻译个人笔记

    区块链分片:<Monoxide: Scale Out Blockchain with Asynchronous Consensus Zones>论文翻译个人笔记 日期:2019年2月26- ...

  9. 翻译漫谈笔记之2科技翻译的特点

    翻译漫谈笔记之科技翻译的特点 1. 科技文献通常是用来讲道理的,所以译者必须准确理解文字表达的道理 2. 科技翻译的译者完全可以适当改动原文 3. 在"顺"与"信&quo ...

最新文章

  1. linux工程师前景_小猿圈预测2019年Linux云计算发展前景
  2. 浅析企业网站页面设计如何才能更吸引用户注意!
  3. php获取longtext字段为空,php – 在longtext字段上准备好的mysqli select语句将返回空...
  4. 使用用户自定义类型作为map的key
  5. SENetSKNet 解读
  6. 汇编语言-019(汇编程序与c\c++相互调用)
  7. Python大数据依赖包安装
  8. 个人管理 - 我是这样偷着做架构的
  9. adb命令重置_android – 擦除数据/通过ADB恢复出厂设置
  10. C++面试高频考点整理--基础
  11. 在Windows 2003环境下配置 PHP 5.2.5 + Apache HTTP Server 2.2.8 + MySQL 6.0
  12. mysql两个修改事务相互阻塞_MySQL 5.7并发复制和mysqldump相互阻塞引起的复制延迟...
  13. 数字逻辑电路课程设计报告
  14. 笔记本设置WiFi热点命令操作
  15. Word提示:“向程序发送命令时出现问题”解决方法
  16. mac --- wifi无法获取ip地址
  17. VS2008下VLC播放器,实现播放、暂停、停止、快进、截图、进度条显示、进度条控制功能
  18. 大型医院PACS系统源码
  19. JMeter之察看结果树
  20. 老嘤学习笔记 python异常处理

热门文章

  1. 幅相曲线matlab,matlab开环幅相曲线
  2. python的__name__
  3. Android模拟器远程,使用Android模拟器进行远程调试
  4. android service 访问数据库,XE5 ANDROID通过webservice访问操作MSSQL数据库
  5. pytorch torch.reshape
  6. javascript arraybuffer
  7. linux chgrp
  8. Windows配置GitBook
  9. Python matplotlib 线图(plt.plot())
  10. 查看mysql连接数_查看mysql 连接数