上次我们看Actor消息机制,我们看到开火-忘记型消息发出(意思是我们只要发个消息给Actor但是不期望有响应)。

技术上来讲, 我们发消息给Actors就是要它的副作用。 这就是这么设计的。除了不响应, 目标Actor当然也可以对消息做以下事情-

1.发送一个响应给发送者(在我们的case里,TeacherActor应该响应一首名言给StudentActor

2.转发一个响应给其他的潜在的受众Actor,他们也可能响应/转发/产生副作用。Routers(路由)和Supervisors(监管)就是这个例子。(我们马上就能看到)


REQUEST & RESPONSE

这次,我们只关注第一点- 请求-响应的周期。

图片说明了我们这次在尝试归档做什么。为了简介,我没有在图中加入ActorSystem, Dispathcer或Mailboxes。

  1. DriverApp发送一个InitSignal(初始化信号)消息给StudentActor.

  2. StudentActor反馈给InitSignal消息并且发送一条QuoteRequest(格言请求)消息给TeacherActor

  3. TeacherActor,像我们在第一次看到的,响应一条QuoteResponse

  4. StudentActor只记录QuoteResponse(格言响应)到控制台/日志记录器。

我们可以写个testcase来验证。

让我们看下这4点的细节:

1. DRIVERAPP发送一个INITSIGNAL消息给STUDENTACTOR

至此,你可能已经猜出DriverApp会做什么。 就4件事:

1) 初始化ActorSystem

//Initialize the ActorSystem
val system = ActorSystem("UniversityMessageSystem")
  1. 创建TeacherActor
//create the teacher actor
val teacherRef = system.actorOf(Props[TeacherActor], "teacherActor")
  1. 创建StudentActor
//create the Student Actor - pass the teacher actorref as a constructor parameter to StudentActor
val studentRef = system.actorOf(Props(new StudentActor(teacherRef)), "studentActor")

你可以看到我把ActorRef的实例TeacherActorStudentActor的构造函数,这样StudentActor可以使用ActorRef发消息给TeacherActor。还有另外的方式达到这个目的(如传入Props),但是这个方法对我们后面看到的Supervisors和Routers会方便点。我们也会即将看到child actors但现在还不是一个好方式 - Student创建Teacher听起来怪怪的吧?

最后,

4) DriverApp会发一个InitSignalStudentActor, z何阳StudentActor就能开始发送QuoteRequest(格言请求)给TeacherActor。

//send a message to the Student Actor
studentRef ! InitSignal

这个DriverClass讲差不多了。 Thread.sleepActorSystem.shutdown在我们最后关闭ActorSystem的时候会在发消息时会等待几秒保证结束。

** DRIVERAPP.SCALA**

package me.rerun.akkanotes.messaging.requestresponse

import akka.actor.ActorSystem
import akka.actor.Props
import me.rerun.akkanotes.messaging.protocols.StudentProtocol._
import akka.actor.ActorRef object DriverApp extends App { //Initialize the ActorSystem
val system = ActorSystem("UniversityMessageSystem") //construct the teacher actor
val teacherRef = system.actorOf(Props[TeacherActor], "teacherActor") //construct the Student Actor - pass the teacher actorref as a constructor parameter to StudentActor
val studentRef = system.actorOf(Props(new StudentActor(teacherRef)), "studentActor") //send a message to the Student Actor
studentRef ! InitSignal //Let's wait for a couple of seconds before we shut down the system
Thread.sleep(2000) //Shut down the ActorSystem.
system.shutdown() }

2. STUDENTACTOR响应给INITSIGNAL消息并且发送一条QUOTEREQUEST消息给TEACHERACTOR###

以及

4. STUDENTACTORTEACHERACTOR接收到QUOTERESPONSE并且将日志记录到控制台/日志记录器###

为什么我把2和4条绑在一起?因为实在太简单了,要是拆开来你要恨死我。

所以,第二点 - StudentActor从DriverApp接到InitSignal消息并且发送QuoteRequest给TeacherActor。

def receive = {
case InitSignal=> {
teacherActorRef!QuoteRequest
}
...
...

就这么多!

第四点 - StudentActor记录从TeacherActor发来的日志消息。

就像我们承诺的:

case QuoteResponse(quoteString) => {
log.info ("Received QuoteResponse from Teacher")
log.info(s"Printing from Student Actor $quoteString")
}

我想你肯定同意现在这个看起来跟伪代码一样。

所以整个的StudentActor类看起来就是这样:

STUDENTACTOR.SCALA###

package me.rerun.akkanotes.messaging.requestresponse

import akka.actor.Actor
import akka.actor.ActorLogging
import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._
import me.rerun.akkanotes.messaging.protocols.StudentProtocol._
import akka.actor.Props
import akka.actor.ActorRef class StudentActor (teacherActorRef:ActorRef) extends Actor with ActorLogging { def receive = {
case InitSignal=> {
teacherActorRef!QuoteRequest
} case QuoteResponse(quoteString) => {
log.info ("Received QuoteResponse from Teacher")
log.info(s"Printing from Student Actor $quoteString")
}
}
}

3. TEACHERACTOR响应QUOTERESPONSE消息###

这就跟我们在fire-n-forget 那里写的代码差不多。

TeacherActor接受一条QuoteRequest消息并且返回一条QuoteResponse

TEACHERACTOR.SCALA###

package me.rerun.akkanotes.messaging.requestresponse

import scala.util.Random

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.actorRef2Scala
import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._ class TeacherActor 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") def receive = { case QuoteRequest => { import util.Random //Get a random Quote from the list and construct a response
val quoteResponse = QuoteResponse(quotes(Random.nextInt(quotes.size))) //respond back to the Student who is the original sender of QuoteRequest
sender ! quoteResponse }
}
}

测试用例TESTCASES###

现在,我们的测试用例会模拟DriverApp。由于StudentActor只是记录消息,我们无法对QuoteResponse消息进行断言,我们只断言消息在EventStream里出现(就像我们之前

说的)

所以,我们的测试用例就像这样:

"A student" must {

    "log a QuoteResponse eventually when an InitSignal is sent to it" in {

      import me.rerun.akkanotes.messaging.protocols.StudentProtocol._

      val teacherRef = system.actorOf(Props[TeacherActor], "teacherActor")
val studentRef = system.actorOf(Props(new StudentActor(teacherRef)), "studentActor") EventFilter.info (start="Printing from Student Actor", occurrences=1).intercept{
studentRef!InitSignal
}
}
}

源码###

整个工程可以在github下载。

下一步,我们会看到怎样使用Akka的schedulers并且用Kamon监控你的Akka应用。


文章来自微信平台「麦芽面包」,微信号「darkjune_think」。转载请注明。

[翻译]AKKA笔记 - ACTOR MESSAGING - REQUEST AND RESPONSE -3的更多相关文章

  1. [翻译]AKKA笔记 -ACTOR SUPERVISION - 8

    失败更像是分布式系统的一个特性.因此Akka用一个容忍失败的模型,在你的业务逻辑与失败处理逻辑(supervision逻辑)中间你能有一个清晰的边界.只需要一点点工作,这很赞.这就是我们要讨论的主题. ...

  2. [翻译]AKKA笔记 - ACTOR生命周期 - 基本 -5

    原文地址:http://rerun.me/2014/10/21/akka-notes-actor-lifecycle-basic/ (请注意这了讨论的生命周期并不包括 preRestart 或者pos ...

  3. 翻译:AKKA笔记 - Actor消息 -1(一)

    从第一篇Akka笔记的介绍中,我们是从很高的高度去观察Akka工具箱中的Actors.在这篇笔记的第二篇,我们会看一下Actors中的消息部分.而且延续上一次的例子,我们还会使用同样的学生与老师的例子 ...

  4. 翻译:AKKA笔记 - Actor消息 -1(二)

    消息 我们只是让QuoteRequest到ActorRef去但是我们根本没见过消息类! 它是这样的: (一个最佳实践是把你的消息类包装在一个完整的对象里以利于更好的组织) TeacherProtoco ...

  5. [翻译]AKKA笔记 - DEATHWATCH -7

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

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

    原文在http://rerun.me/2014/10/06/akka-notes-actorsystem-in-progress/ 像我们前面看到的,我们可以用ActorSystem的actorof方 ...

  7. [翻译]AKKA笔记 - LOGGING与测试ACTORS -2 (一)

    在前两章 ( 一 , 二 ) ,我们大致讲了Actor和message是怎么工作的,让我们看一下日志和测试我们的 TeacherActor . RECAP 这是上一节我们的Actor代码: class ...

  8. [翻译]AKKA笔记 - 有限状态机 -1

    原文地址:http://rerun.me/2016/05/21/akka-notes-finite-state-machines-1/ 我最近有个机会在工作上使用了Akka FSM,是个非常有趣的例子 ...

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

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

随机推荐

  1. heap c++ 操作 大顶堆、小顶堆

    在C++中,虽然堆不像 vector, set 之类的有已经实现的数据结构,但是在 algorithm.h 中实现了一些相关的模板函数.下面是一些示例应用 http://www.cplusplus.c ...

  2. 爱上WPF,努力才会有希望!

    从WinForm转向WPF开发已经有两个多月了,通过不断深入地学习与运用,现在是越来越爱它了.它实在是太强大了.运用WPF,你不仅可以做Win界面,也可以很快转向Web开发,因为Silverlight ...

  3. 通过Guid获取DirectoryEntry对象

    绑定DirectoryEntry对象通常有两种方法,一种是通过字符串(如通过ADsPath),一种是通过Guid(参见:http://msdn.microsoft.com/zh-cn/library/ ...

  4. 复星昆仲杨光:VR行业四大痛点

    2016年,可是说是VR产业的爆发之年,从公司层面到资本层面都对VR产业给予了厚望,期望其能够在移动互联网之后带来革命性的突破,掀起新一轮技术主导的商业革命.而创业者们已经跃跃欲试,期望在资本的支持下 ...

  5. 基于VC的ACM音频编程接口压缩Wave音频(二)

    (二)获取CODECs 的 信 息  ACM 的API 函 数 定 义 在 头 文 件msacm.h 中, 除 此 之 外, 对ACM 编 程 还 必 须 包 含 头 文 件mmsystem.h,mm ...

  6. java-注解

    概念 Annontation是Java5开始引入的新特征.中文名称一般叫注解.它提供了一种安全的类似注释的机制,用来将任何的信息或元数据与程序元素(类.方法.成员变量等)进行关联.更通俗的意思是为程序 ...

  7. 基于Linux的WebSphere性能调优与故障诊断

    一.关于was数据源等问题的配置 (1)关于was数据源连接池的最大.最小配置多大合适?怎样去计算? (2)关于JVM的配置,64位系统,64位WAS,最值小和最大配置多大最优?怎样去计算? (3)应 ...

  8. Jquery的multifile使用随记

    1.多文件上传: 2.如上几个验证不重复,和限制上传数量的验证显示的是英文,改成中文文本时,如果不用国标解码,到时候提示框会出现乱码现象.所以一般需要中文显示的时候,我们应该这样做: 拿denied做 ...

  9. kvm虚拟机--存储池配置梳理(转)

    1.创建基于文件夹的存储池(目录) 2.定义存储池与其目录 1 # virsh pool-define-as vmdisk --type dir --target /data/vmfs 3.创建已定义 ...

  10. Windows Server 2003搭建邮件服务器

    Windows Server 2003搭建邮件服务器 由于Windows Server 2003默认是没有安装我们搭建邮件服务器所需要的POP3和SMTP服务的,因此需要我们自己来安装.方法如下: 1 ...