Akka 中 Actorref.tell 和 inbox.send 的区别

2023-11-26

所以我开始学习 Akka 并尝试 typesafe 中的示例。 所以 Hello Akka 应用程序有以下代码:

    import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
import scala.concurrent.duration._

case object Greet
case class WhoToGreet(who: String)
case class Greeting(message: String)

class Greeter extends Actor {
  var greeting = ""

  def receive = {
    case WhoToGreet(who) => greeting = s"hello, $who"
    case Greet           => sender ! Greeting(greeting) // Send the current greeting back to the sender
  }
}

object HelloAkkaScala extends App {

  // Create the 'helloakka' actor system
  val system = ActorSystem("helloakka")

  // Create the 'greeter' actor
  val greeter = system.actorOf(Props[Greeter], "greeter")

  // Create an "actor-in-a-box"
  val inbox = Inbox.create(system)

  // Tell the 'greeter' to change its 'greeting' message
  greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

  // Ask the 'greeter for the latest 'greeting'
  // Reply should go to the "actor-in-a-box"
  inbox.send(greeter, Greet)

  // Wait 5 seconds for the reply with the 'greeting' message
  val Greeting(message1) = inbox.receive(5.seconds)
  println(s"Greeting: $message1")

  // Change the greeting and ask for it again
  greeter.tell(WhoToGreet("typesafe"), ActorRef.noSender)
  inbox.send(greeter, Greet)
  val Greeting(message2) = inbox.receive(5.seconds)
  println(s"Greeting: $message2")

  val greetPrinter = system.actorOf(Props[GreetPrinter])
  // after zero seconds, send a Greet message every second to the greeter with a sender of the greetPrinter
  system.scheduler.schedule(0.seconds, 1.second, greeter, Greet)(system.dispatcher, greetPrinter)

}

// prints a greeting
class GreetPrinter extends Actor {
  def receive = {
    case Greeting(message) => println(message)
  }
}

现在我陷入了理解之间的区别,

greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

and

inbox.send(greeter, Greet)

根据我的理解,演员在结束时开始自己的线程

val inbox = Inbox.create(system)

有人可以解释一下 Actorref.tell 到底做了什么,然后 Inbox.send 行到底实现了什么。


的目的tell,也表示为!是向演员发送消息。当参与者通过消息传递进行交流时,tell是用于支持消息传递的机制。它对于调用者来说是异步的,因此一旦调用者调用tell,它们与目标参与者实例对该消息的接收和处理分离。在这个特定的示例中,代码使用tell 来使greeter actor 更新其内部状态。由于此交互不会导致任何类型的响应(接收参与者不会将消息发送回发送者以响应此请求),tell这里单独就足够了。

为了从问候者那里获得问候响应,交互略有不同。在此交互中,发送者期待响应消息。这种类型的请求/响应交互可以通过ask (i.e. ?)其中调用者得到一个Future返回将在接收者回复时完成,但是ask这里没有使用。在此示例中,编码器通过使用Inbox相反,它可以充当演员,并且消除了对 future 的需要。收件箱必须看起来像ActorRef到接收器,允许它使用以下行将响应路由回它:

sender ! Greeting(greeting)

The sender()方法返回ActorRef当前正在处理的消息的发送者。这Inbox必须能够将自己表示为ActorRef为了这个工作。但正如我之前所说,你也可以使用ask在这里让请求/响应交互工作。我认为这只是一个选择的问题。底线是tell用于即发即忘交互模型和收件箱(或其他演员或ask) 可以在需要请求/响应语义时使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Akka 中 Actorref.tell 和 inbox.send 的区别 的相关文章

随机推荐

  • Haxe - 打印命令行参数

    使用 Haxe 编程语言 是否可以打印传递给应用程序的命令行参数 我正在尝试在 Haxe 中重写这个 Java 程序 它只是打印命令行参数 public class JavaExample public static void main S
  • 在没有身份的情况下使用 Bearer/Jwt 授权

    我正在使用 Asp 5 开发 Web API 并阅读了一些有关 Web API 的文档 意识到我需要 Bearer 授权 经过查找 没有发现任何未经授权使用的文档或样本Aspnet Identity 我有自己的会员资格 但我不想使用Iden
  • 实现命令模式

    我正在设计一个应用程序 我想使用命令模式用于撤消 重做目的 我对命令模式做了一些研究 但我唯一不明白的是 命令是否应该具有撤消和重做方法 或者我应该创建两个单独的命令 一个用于撤消 一个用于重做 并从主命令本身 命令对象本身应该实现撤消 重
  • 单击 Facebook Like 按钮后显示内容

    我有一个网页部分 我只希望人们在单击 Facebook Like 按钮后能够访问该部分 如何隐藏该特定区域 然后仅在有人单击 赞 按钮后才显示它 至于 Facebook Like 代码 如下所示
  • 了解 PHP &(与号、按位与)运算符

    我经常使用 var 1 在我的代码中 如果 var是奇数 如果是偶数则为 false 但 实际上有什么作用呢 是二进制的and 如果你有一个二进制值 并且你and与另一个二进制值 则结果将是按位and两者之中 一个例子 01101010 0
  • 如何检索原始函数的形式?

    至少目前 这对我来说是一个学习练习 所以实际功能或其复杂性不是问题 假设我编写一个函数 其参数列表包含一些输入变量和函数名称 以字符串形式传递 然后 该函数在内部计算一些变量 并 决定 如何将它们提供给我传入的函数名称 对于非原始函数 我可
  • Chrome 扩展:webRequest.onBeforeSendHeaders 行为奇怪

    我正在尝试向 Chrome 扩展程序中的某些 AJAX 请求添加 Referer HTTP 标头 您无法直接在 AJAX 请求中更改它 因此我尝试使用网络请求 API chrome webRequest onBeforeSendHeader
  • Laravel Mail::send() 发送到多个收件人或密件抄送地址

    我似乎无法成功发送至multiple使用 Laravel 时的地址Mail send 回调 但是当我只指定时 代码确实有效one接受者 我尝试过链接 for example emails array email protected emai
  • 无法在已停止的 SparkContext 上调用方法

    当我运行以下测试时 它会抛出 无法在已停止的 SparkContext 上调用方法 可能的问题是我使用TestSuiteBase和流 Spark 上下文 在行val gridEvalsRDD ssc sparkContext paralle
  • 使用 linq 删除列表中的重复项

    我有课Items with properties Id Name Code Price 名单Items填充有重复的项目 例如 1 Item1 IT00001 100 2 Item2 IT00002 200 3 Item3 IT00003 1
  • 使用数据注释的有条件必需的属性

    我有一堂这样的课 public class Document public int DocumentType get set Required public string Name get set Required public strin
  • JAVA使用google语音识别API

    我正在尝试使用谷歌语音识别 API 这是我写的代码 http pastebin com zJEhnJ74 有用 我从服务器得到答案 status 5 id 8803471b14a2310dfcf917754e8bd4a7 1 hypothe
  • MySQL - 唯一外键

    我必须使其中一个外键唯一 问题是 我从 phpMyAdmin 收到以下消息 The following indexes appear to be equal and one of them should be removed consign
  • 查询 DNS 服务记录以查找主机名和 TCP/IP

    在一篇关于生命科学标识符 see LSID Tester 用于测试生命科学标识符解析服务的工具 罗德里克 DM 佩奇博士写道 给定 LSID urn lsid ubio org namebank 11815 在 DNS 中查询 SRV 记录
  • 从已使用的命名空间中排除类

    我所有 C 文件的第一条语句是 使用系统 现在 在框架版本 4 中 该命名空间包含一个名为 Action 的类 这也是我自己的代码中经常使用的命名空间中的类的名称 现在当然有冲突 当然 我可以通过在我之前使用 Action 的地方使用显式的
  • C++ 中的构造函数和对象数组

    我正在尝试用 C 创建一个应用程序 在应用程序中 我有默认构造函数和另一个带有 3 个参数的构造函数 用户从键盘提供一个整数 该整数将用于使用非默认构造函数创建对象数组 不幸的是 到目前为止我还无法完成它 因为我在创建对象数组时遇到问题 它
  • Rails:Turbo Stream Broadcast 不更新视图

    我有一个 Turbo Stream 它没有更新视图 我不知道为什么 我在类似的配置中设置了另外两个广播 运行良好 从我所看到的来看 一切看起来都应该正常工作 我只是没有在前端获得更新 我错过了一些明显的事情吗 partial div div
  • 打开文件时出现“无效参数”错误(并且不读取文件)

    我正在尝试编写代码 在文本文件中获取 2 个数字 然后将它们分开 将答案显示为最重的分数 当我在程序中输入自己的值时 我已经让分数部分开始工作 但我无法让程序识别文本文件 我尝试将它们放在同一目录中并放置文件的完整系统路径 但到目前为止没有
  • 使用供应商目录中的 autoloader.php 自动加载无法正常工作

    我在自动加载 Composer 时遇到问题 因为自动加载器无法解析 Doctrine ORM Mapping Table 对于单元测试 我创建了带有典型注释的学说实体类
  • Akka 中 Actorref.tell 和 inbox.send 的区别

    所以我开始学习 Akka 并尝试 typesafe 中的示例 所以 Hello Akka 应用程序有以下代码 import akka actor ActorRef ActorSystem Props Actor Inbox import s