消息##

我们只是让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. 用Backbone.js创建一个联系人管理系统(四)

    原文: Build a Contacts Manager Using Backbone.js: Part 4 这一系列教程的第四部分,教我们如何完成对已经存在的Contacts进行编辑和保存. 本教程 ...

  2. 拦截js方法备忘录

    很明显,以下代码拦截了fusion2.dialog.invite,然后在页面执行fusion2.dialog.invite方法的时候修改了参数中的img. <script> var old ...

  3. C# v3微信 access token 过期处理的问题

    //记录access token 申请时的时间 private static DateTime GetAccessToken_Time; /// <summary> /// 过期时间为72 ...

  4. Java正则表达式的解释说明

    1.字符x    字符 x.例如a表示字符a\\    反斜线字符.在书写时要写为\\\\.(注意:因为java在第一次解析时,把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1 ...

  5. Qt ffmpeg环境搭建

    ffmpeg下载地址:https://ffmpeg.zeranoe.com/builds/ 版本选择第一个,然后多少位看自己的pc(我的是64),右边对应三个都要下载,Static,Shared,De ...

  6. 异常:System.Data.EvaluateException: 未找到列[District].

    异常:System.Data.EvaluateException: 未找到列[District]. 这里存在的问题不一定是说,数据源表没有该字段.此问题在于数据库字段包含空格字符.

  7. redis cluster节点管理测试

    ####redis v3.2.0###添加节点:1.添加master节点 170 ./redis-trib.rb add-node 127.0.0.1:7007 127.0.0.1:7001 171 ...

  8. iOS 选择的照片或者拍照的图片上添加日期水印

    1..引入框架 #import "CLLocation+GPSDictionary.h"#import "NSDictionary+CLLocation.h" ...

  9. 黑马程序员-循环引用问题和weak

    使用weak reference(弱引用)来避免retain cycle 对一个对象发送retain消息会创建对这个对象的强引用(strong reference).如果两个对象都有一个强引用指向对方 ...

  10. [Django] Setting up Django Development Environment in Ubuntu 14.04

    1. Python Of course you will need Python. Still Python 2.7 is preferred, however if you would like t ...