akka 2.0向自己发送消息

igx*_*igx 1 scala akka

使用Akka 2.0尝试向自己发送消息(使用ask模式)

import akka.pattern.ask
import scala.concurrent.{Await, Future}
import akka.actor.{Props, Actor, ActorSystem}
import scala.concurrent.duration._
import akka.util.Timeout
object askTest extends App{
   implicit val timeout = Timeout(5 seconds)
   val system = ActorSystem("AskTestSystem")
   val myActor = system.actorOf(Props(new TestActor), name = "myActor")
   val future: Future[Foo] = ask(myActor, Foo("test")).mapTo[Foo]
   val result = Await.result(future, timeout.duration)
   println(result)
}
case class Foo(name:String){
  override def toString = "Foo "+name
}

  class TestActor extends Actor {
  def receive = {
    case Foo(a) => self ! Foo("buzz "+a)
    case any => println(any+" that was unexpected")
  }
 }
Run Code Online (Sandbox Code Playgroud)

但它与Timeout异常崩溃并带有以下跟踪:

 Exception in thread "main" java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]
    at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:96)
    at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:100)
    at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:107)
    at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
    at scala.concurrent.Await$.result(package.scala:107)
    at akkaTest.askTest$delayedInit$body.apply(askTest.scala:33)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.App$$anonfun$main$1.apply(App.scala:71)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
    at scala.App$class.main(App.scala:71)
    at akkaTest.askTest$.main(askTest.scala:13)
    at akkaTest.askTest.main(askTest.scala)
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 6

您的代码执行您告诉它要执行的操作:actor无限期地向自己发送消息.因为它将消息发送给除self以外的任何人,所以您的ask模式无法正常工作,因为ask正在等待将消息发送给发件人,而不是自己.

self是对当前actor的引用,当您希望actor向自己发送消息时使用它.sender是对已发送当前正在处理的消息的actor的引用.如果您想"回复"发件人,请使用它.

askpattern创建一个隐式actor,它sender在目标actor中成为引用 - 这是非常自然的.因此,您需要更改self ! Foo("buzz " + a)sender ! Foo("buzz " + a),并且您的代码将起作用.


Ale*_*nov 6

您可以将邮件发送到self,但不能等待回复。因为直到完成对当前消息的处理,您才收到新消息;如果使用ask,您将在得到对新消息的答复之前完成对当前消息的处理!因此,您正在创建一个僵局。

但是,对于所涉及的代码,您根本要求self答复。由创建的actor ask正在等待来自的答复myActor,但没有得到答复(因为的代码TestActor未发送任何答复self而是发送了一条消息给)。

您可以self ! message通过稍作更改来查看效果TestActor

case class Bar(name: String)

class TestActor extends Actor {
  def receive = {
    case Foo(a) => self ! Bar(a)
    case Bar(a) => println("Got a message to self: " + a)
    case any => println(any+" that was unexpected")
  }
}
Run Code Online (Sandbox Code Playgroud)