Scala 阿克卡中Actorref.tell和inbox.send的区别
因此,我开始学习Akka,并在typesafe中尝试这些示例。 因此,Hello Akka应用程序具有以下代码:Scala 阿克卡中Actorref.tell和inbox.send的区别,scala,akka,Scala,Akka,因此,我开始学习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
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)
及
据我所知,演员在故事的结尾开始了自己的故事
val inbox = Inbox.create(system)
有人能解释一下Actorref.tell到底做了什么,然后Inbox.send行到底实现了什么 当您执行以下操作时,您直接与
ActorRef
greeter.tell(WhoToGreet("akka"), ActorRef.noSender)
另一方面,当你使用收件箱时
,你处理的不是一个演员,而是一个演员。当您不想创建自己的参与者,但仍然希望与其他参与者异步交互时,这一点非常有用。请看
收件箱是一个类似于参与者的对象,可以从外部进行查询。它包含一个参与者,该参与者的引用可以像往常一样传递给其他参与者,并且它可以监视其他参与者的生命周期
参与者在线程池上运行(使用调度程序配置)。您可以通过配置或在代码中输入参与者用于执行的调度程序来决定 告诉的目的,也表示为
代码>是向参与者发送消息。当参与者通过消息传递进行通信时,tell
是用于支持该消息传递的机制。它与调用者是异步的,因此一旦调用者调用tell
,它们就与目标参与者实例接收和处理该消息的过程分离。在这个特定的示例中,代码使用tell使迎宾参与者更新其内部状态。由于此交互不会导致任何类型的响应(接收参与者没有将消息发送回发送者以响应此请求),tell
在这里就足够了
为了从问候者那里得到问候的回应,互动略有不同。在这种交互中,发送方希望收到响应消息。这种类型的请求/响应交互可以通过ask
(即?
)进行,在这种交互中,调用者获得一个未来的
,当接收者回复时将完成,但此处未使用ask
。在本例中,编码人员通过使用收件箱
获得请求/响应语义,该收件箱可以充当参与者,从而消除了对未来的需求。对于接收者来说,收件箱必须看起来像一个ActorRef
,允许其使用以下行将响应发送回收件箱:
sender ! Greeting(greeting)
sender()
方法返回当前正在处理的消息中发送的人的ActorRef
。收件箱
必须能够将自己表示为一个ActorRef
,这样才能工作。但正如我前面所说,您也可以在这里使用ask
来实现请求/响应交互。我认为这只是选择的问题。底线是,tell
用于fire-and-forget交互模型,当需要请求/响应语义时,可以使用收件箱(或其他参与者或ask
)。这是否意味着如果我注释掉“inbox.send(greater,Greet)”呼叫,我仍然会看到“receive”方法在Greeter actor类@SomBhattacharyya中被调用,在该示例中,receive
partial函数将被调用两次;一个来自WhoToGreet
的tell
,另一个来自收件箱。发送问候
邮件的。如果注释掉收件箱中的send
,则receive
只会对whotoreet
消息调用一次。
sender ! Greeting(greeting)