消息##

我们只是让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. jquery双击事件

    <html> <head><meta http-equiv="Content-Type" content="text/html; chars ...

  2. Java File创建新目录和文件

    创建目录 当不存在目录aa文件夹时: File file1=new File("/aa"); Boolean aa=file.mkdir();// true File file1= ...

  3. exp

    想将远程机器上的数据库备份,搞了一上午,终于解决了: exp 用户名/密码@ip/service名 file=地址+文件名

  4. STM32 DMA模块的配置与使用

    DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输.无须CPU的干预,通过DMA数据可以快速地移动.这就节省了CPU的资源来做其他操作. 有多少个DMA资源 ...

  5. 猿团YTFCloud--5分钟自制APP,开发从未如此简单

    9月15日,YTFCloud将正式开启内测, 这意味着猿团YTF框架产品线全面升级.同时,公测过后,YTFCloud的APP线上DIY服务将面向所有用户,让人人都能成为APP“开发商”. 什么是YTF ...

  6. nginx日常运维

    pid丢失办法: 1.查找nginx进程ID ps -ef | grep nginx 2.将进程ID写入pid > /tmp/nginx.pid 3.重启nginx

  7. JS动态级联菜单

    JS动态级联菜单是前端常用的一个功能,特此抽时间研究了下,附上代码 <html> <head> <meta charset="utf-8" /> ...

  8. Proximal Gradient Descent for L1 Regularization

    [本文链接:http://www.cnblogs.com/breezedeus/p/3426757.html,转载请注明出处] 假设我们要求解以下的最小化问题:                     ...

  9. css各项水平居中

    当被设置元素为块状元素时用text-align:center就不起作用了,这也分两种情况,定宽块状元素和不定宽块状元素. 一.定宽块状元素:快状元素的宽度width为固定值,之后我们可以将左右marg ...

  10. WEB开发之路——基础部分

    WEB开发之路 受BBC的<BBC: Brain Story>和<BBC: The Brain - A Secret History>的影响,我一直有志于探究人类大脑,2015 ...