1.一个actor 总有一个父节点
system.actorOf() 创建是系统actor的子actor
context.actorOf() 创建是该actor的子actor
2.
import akka.actor.{Actor, ActorSystem, Props}
class PrintMyActorRefActor extends Actor {
override def receive: Receive = {
case "test" =>
val secondRef = context.actorOf(Props.empty, "second-actor")
println(s"Second: $secondRef")
}
}
object ActorHierarchyExperiments extends App {
val system = ActorSystem("testSystem")
val firstRef = system.actorOf(Props[PrintMyActorRefActor], "first-actor")
println(s"First: $firstRef")
firstRef ! "test"
}
输出结果为:
First: Actor[akka://testSystem/user/first-actor#-1025274301]
Second: Actor[akka://testSystem/user/first-actor/second-actor#-467743039]
我们可以看到输出的子actor包含了父actor的路径
3.actor的生命周期
当一个actor结束的时候,它的所有子actor都会递归结束
一般用context.stop(self) 结束自身actor
结束其他actor 用发送“毒药”的方式 而不是用context.stop(actorRef),一般有preStart() postStop()
preStart() :在actor 启动还没有接受第一个消息时用
postStop():在actor结束前,没有处理消息的时候
例子:
class StartStopActor1 extends Actor {
override def preStart(): Unit = {
println("first started")
context.actorOf(Props[StartStopActor2], "second")
}
override def postStop(): Unit = println("first stopped")
override def receive: Actor.Receive = {
case "stop" => context.stop(self)
}
}
class StartStopActor2 extends Actor {
override def preStart(): Unit = println("second started")
override def postStop(): Unit = println("second stopped")
// Actor.emptyBehavior is a useful placeholder when we don't
// want to handle any messages in the actor.
override def receive: Actor.Receive = Actor.emptyBehavior
}
object test extends App{
val system: ActorSystem = ActorSystem("test")
//#create-actors
// Create the printer actor
val first: ActorRef = system.actorOf(Props[StartStopActor1], "printerActor")
first ! "stop"
}
输出结果为:
first started
second started
second stopped
first stopped
4.当子actor失败的时候
例子:
class SupervisingActor extends Actor {
val child = context.actorOf(Props[SupervisedActor], "supervised-actor")
override def receive: Receive = {
case "failChild" => child ! "fail"
}
}
class SupervisedActor extends Actor {
override def preStart(): Unit = println("supervised actor started")
override def postStop(): Unit = println("supervised actor stopped")
override def receive: Receive = {
case "fail" =>
println("supervised actor fails now")
throw new Exception("I failed!")
}
}
object test extends App{
val system: ActorSystem = ActorSystem("test")
//#create-actors
// Create the printer actor
val first: ActorRef = system.actorOf(Props[SupervisingActor], "supervisingActor")
first ! "failChild"
}
输出结果为:
supervised actor started
supervised actor fails now
supervised actor stopped
supervised actor started
[ERROR] [01/10/2018 16:00:28.230] [test-akka.actor.default-dispatcher-3] [akka://test/user/supervisingActor/supervised-actor] I failed!
java.lang.Exception: I failed!
at SupervisedActor$$anonfun$receive$2.applyOrElse(test.scala:21)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
at akka.actor.ActorCell.invoke(ActorCell.scala:456)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
at akka.dispatch.Mailbox.run(Mailbox.scala:219)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
我们可以看到当actor挂了的时候,它立刻就重启了