翻译:AKKA笔记 - Actor消息 -1(二)
消息##
我们只是让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。在底层实现中,当我们创建一个ActorSystem和ActorRef的时候,一个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方法做的所有事是
- 根据模式匹配QuoteRequest
- 从格言的静态列表(list)中随机选取一个格言
- 构造一个QuoteResponse
- 将QuoteResponse打印到控制台
代码##
完整项目可以在github下载。
文章来自微信平台「麦芽面包」,微信号「darkjune_think」。转载请注明。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?