Actor - Send Messages

Actor 发送消息 tell (!) vs ask (?) vs forward

Tell

actorRef ! message
发送干别的去了,不管后果

Ask

import akka.actor.{ActorSystem, DeadLetter}
import akka.util.Timeout
import akka.pattern.{ask, pipe}

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.{Failure, Success}


final case class Result(x: Int)

case object Request


object AkkaActor extends App {

import DemoActor._

println("Hello, world!")
val system = ActorSystem("mySystem")

import system.dispatcher

val demoActor = system.actorOf(props(42), "demoActor")
val pipeActor = system.actorOf(PipeActor.props, "pipeActor")

system.eventStream.subscribe(demoActor, classOf[DeadLetter])
println(s"demoActor created !")
demoActor ! 88
// println(s"ready to kill demoActor's child")
// demoActor ! "kill"

implicit val timeout = Timeout(5 seconds) // needed for `?` below

val f: Future[Result] =
for {
x <- ask(demoActor, Request).mapTo[Int] // call pattern directly
} yield Result(x)

f pipeTo pipeActor

f onComplete {
case Success(x) => println(s"success $x")
case Failure(e) => println(s"fail ${e.getMessage} in callback of future")
}
}
  1. 隐式 timeout ask模式下如果超时 会有 AskTimeoutException
  2. 隐式 dispatch 后面的异步Future需要
  3. ask模式要求接受信息方 返回结果, 返回的是Future[T] 类型
  4. pipe 可以将结果转交给其他actor
  5. 如果接受信息方 出现exception 需额外处理来结束异步Future
 case Request =>
try {
throw new Exception("ask for exception")
sender() ! 90
} catch {
case e: Exception => sender() ! Status.Failure(e)
// throw e
}

case e: Exception => sender() ! Status.Failure(e) 主动结束Future
如果不做的话,Future的不会complete 也就是这句不会执行 case Failure(e) => println(s"fail ${e.getMessage} in callback of future")

Output

Hello, world!
magicNumber: 42
demoActor created !
create myActor: akka://mySystem/user/demoActor/myActor
Actor[akka://mySystem/user/demoActor/myActor#983047950] preStart
watching myActor
get actorRef: Actor[akka://mySystem/user/demoActor/myActor#983047950]
fail ask for exception in callback of future
[INFO] [04/28/2017 00:40:46.015] [mySystem-akka.actor.default-dispatcher-4] [akka://mySystem/user/demoActor/myActor] I was greeted by Vincent Guo with params 88.

Forward

target forward message

类似二传手的作用,可以做小路由,sender是原来的sender被带入