消息##

我们只是让QuoteRequest到ActorRef去但是我们根本没见过消息类!

它是这样的:

(一个最佳实践是把你的消息类包装在一个完整的对象里以利于更好的组织)

TeacherProtocol

package me.rerun.akkanotes.messaging.protocols

object TeacherProtocol{

  case class QuoteRequest()
case class QuoteResponse(quoteString:String) }

就像你知道的,QuoteRequest是用来发给TeacherActor的。Actor应该响应一个QuoteResponse回来。

分发者DISPATCHER和邮箱MAILBOX##

ActorRef将消息处理功能委托给Dispatcher。在底层实现中,当我们创建一个ActorSystemActorRef的时候,一个Dispatcher和一个MailBox也被创建出来了。让我们看下他们。

邮箱MailBox###

Actor有一个MailBox(稍后我们会看到一个特例)。在我们的例子里,每个老师都有一个邮箱(mailbox)。老师需要检查邮箱(mailbox)并且处理消息。在Actor的世界里,是另一种样子-邮箱(mailbox),当它有机会它会使用Actor来完成它的工作。

邮箱维护一个先入先出的队列来保存和处理消息- 跟我们常规的收件箱有点不一样,常规的收件箱总是最新的邮件在最上面。

现在,分发者 dispatcher###

分发者做的事很有趣。表面上看,分发者只是从ActorRef拿到消息然后将消息发给MailBox。但是在这个场景里有个很神奇的事情:

分发者包装了ExecutorService(ForkJoinPool或者ThreadPoolExecutor)。 它用这个ExecutorService来执行MailBox

看一下这个Dispathcer里的片断:

protected[akka] override def registerForExecution(mbox: Mailbox, ...): Boolean = {
...
try {
executorService execute mbox
...
}

什么?你说你执行MailBox?###

是的。我们已经看到了MailBox将所有消息维护在一个队列里。当Executor运行MailBox时,MailBox必须是一个线程(Thread)。就是这样,这就是MailBox的声明和构造函数。

这里是Mailbox的签名

private[akka] abstract class Mailbox(val messageQueue: MessageQueue) extends SystemMessageQueue with Runnable

TEACHER ACTOR##

MailBox,当它的run方法被调用时,从队列里获取一条消息并把它发给Actor来处理。

在你将消息告知(tell)ActorRef的时候一定会调用到目标Actor的receive方法。

这里的TeacherActor是个基本类,维护一个格言列表(List)并自带能处理消息的方法receive

看下这里:

TeacherActor.scala

package me.rerun.akkanotes.messaging.actormsg1

import scala.util.Random

import akka.actor.Actor
import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._ /*
* Your Teacher Actor class.
*
* The class could use refinement by way of
* using ActorLogging which uses the EventBus of the Actor framework
* instead of the plain old System out
*
*/ class TeacherActor extends Actor { 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))) println (quoteResponse) } } }

TeacherActor只接受一种消息格式-QuoteRequest(实际上,这个让模式匹配默认case的方式是个好实践,但这儿还是有个有趣的故事)

receive方法做的所有事是

  1. 根据模式匹配QuoteRequest
  2. 从格言的静态列表(list)中随机选取一个格言
  3. 构造一个QuoteResponse
  4. 将QuoteResponse打印到控制台

代码##

完整项目可以在github下载。


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

翻译:AKKA笔记 - Actor消息 -1(二)的更多相关文章

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

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

  2. [翻译]AKKA笔记 - ACTOR MESSAGING - REQUEST AND RESPONSE -3

    上次我们看Actor消息机制,我们看到开火-忘记型消息发出(意思是我们只要发个消息给Actor但是不期望有响应). 技术上来讲, 我们发消息给Actors就是要它的副作用. 这就是这么设计的.除了不响 ...

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

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

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

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

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

    3.THROW IN A LOGBACK.XML 现在我们把SLF4J日志配置在logback. <?xml version="1.0" encoding="UTF ...

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

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

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

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

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

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

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

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

随机推荐

  1. html5表单验证

    表单验证为终端用户检测无效的数据并标记这些错误,是一种用户体验的优化. 下面展现浏览器自带的验证功能也可在移动端中查看: HTML部分: <!DOCTYPE html> <html ...

  2. js中replace的回调函数使用。

    这只是一个小问题,但是之前并没有发现.这个问题就是replace的第二个函数是支持回调函数的. var ext = new RegExp('f','g'); 1.str.replace(ext ,1) ...

  3. Win10专业版激活方法可查版本

    Win10专业版激活步骤 ------安装Win10专业版,请win+R,键入winver回车,可查看版本------ 1.点击左下角windows按钮,找到设置并打开,依次点击"更新和安全 ...

  4. 实现十进制无符号整数m到十六进制数的转换功能

    /*利用顺序栈结构,编写算法函数void Dto16(unsigned int m)实现十进制无符号整数m到十六进制数的转换功能.*//******************************** ...

  5. CreateFile() 打开u盘 物理设备

    //以下是用的vs2010 windows7 64 管理员权限编译成功的 HANDLE hDev = CreateFile(TEXT("\\\\.\\PhysicalDrive1" ...

  6. 编译器工具 Flex Bison for Windows 简单入门例子

    最近从事一个系统仿真软件的开发,里面定义了自己的描述性语言MSL, MSL语言经FlexBison转换成C语言,然后用C编译器来编译并计算仿真. 现在领域驱动开发比较热门,有机会定义自己的语言对程序员 ...

  7. [UCSD白板题] Primitive Calculator

    Problem Introduction You are given a primitive calculator that can perform the following three opera ...

  8. [UCSD白板题] Binary Search

    Problem Introduction In this problem, you will implemented the binary search algorithm that allows s ...

  9. Hive几种数据导出方式

    Hive几种数据导出方式 今天我们再谈谈Hive中的几种不同的数据导出方式.可以根据导出的地方不一样,将这些方式分为三种: (1).导出到本地文件系统: (2).导出到HDFS中: (3).导出到Hi ...

  10. code review

    代码审核,开发者代码完工,就可以下一个环节,即代码审核,通过代码审核,可以看到多个开发者的代码规范,隐藏的BUG,一些注释等规范. 通过代码审核,我们开发者可以互相学习,使得代码逻辑正确,重用