Separate class for SystemGuardian, see #2552
* Also checks that the Terminated originates for user guardian
This commit is contained in:
parent
6f727ecd29
commit
dec3184dfa
2 changed files with 28 additions and 9 deletions
|
|
@ -303,7 +303,7 @@ private[akka] case class StopChild(child: ActorRef)
|
||||||
/**
|
/**
|
||||||
* INTERNAL API
|
* INTERNAL API
|
||||||
*/
|
*/
|
||||||
private[akka] object Guardian {
|
private[akka] object SystemGuardian {
|
||||||
/**
|
/**
|
||||||
* For the purpose of orderly shutdown it's possible
|
* For the purpose of orderly shutdown it's possible
|
||||||
* to register interest in the termination of systemGuardian
|
* to register interest in the termination of systemGuardian
|
||||||
|
|
@ -390,8 +390,26 @@ class LocalActorRefProvider(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Guardian(override val supervisorStrategy: SupervisorStrategy, isSystem: Boolean) extends Actor {
|
/*
|
||||||
import Guardian._
|
* Root and user guardian
|
||||||
|
*/
|
||||||
|
private class Guardian(override val supervisorStrategy: SupervisorStrategy) extends Actor {
|
||||||
|
|
||||||
|
def receive = {
|
||||||
|
case Terminated(_) ⇒ context.stop(self)
|
||||||
|
case StopChild(child) ⇒ context.stop(child)
|
||||||
|
case m ⇒ deadLetters ! DeadLetter(m, sender, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
// guardian MUST NOT lose its children during restart
|
||||||
|
override def preRestart(cause: Throwable, msg: Option[Any]) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System guardian
|
||||||
|
*/
|
||||||
|
private class SystemGuardian(override val supervisorStrategy: SupervisorStrategy) extends Actor {
|
||||||
|
import SystemGuardian._
|
||||||
|
|
||||||
var terminationHooks = Set.empty[ActorRef]
|
var terminationHooks = Set.empty[ActorRef]
|
||||||
|
|
||||||
|
|
@ -400,13 +418,14 @@ class LocalActorRefProvider(
|
||||||
// a registered, and watched termination hook terminated before
|
// a registered, and watched termination hook terminated before
|
||||||
// termination process of guardian has started
|
// termination process of guardian has started
|
||||||
terminationHooks -= a
|
terminationHooks -= a
|
||||||
case Terminated(_) ⇒
|
case Terminated(`guardian`) ⇒
|
||||||
// time for the guardian to stop, but first notify all the
|
// time for the guardian to stop, but first notify all the
|
||||||
// termination hooks, they will reply with TerminationHookDone
|
// termination hooks, they will reply with TerminationHookDone
|
||||||
// and when all are done the guardian is stopped
|
// and when all are done the guardian is stopped
|
||||||
context.become(terminating)
|
context.become(terminating)
|
||||||
terminationHooks foreach { _ ! TerminationHook }
|
terminationHooks foreach { _ ! TerminationHook }
|
||||||
stopWhenAllTerminationHooksDone()
|
stopWhenAllTerminationHooksDone()
|
||||||
|
case Terminated(_) ⇒
|
||||||
case StopChild(child) ⇒ context.stop(child)
|
case StopChild(child) ⇒ context.stop(child)
|
||||||
case RegisterTerminationHook if sender != context.system.deadLetters ⇒
|
case RegisterTerminationHook if sender != context.system.deadLetters ⇒
|
||||||
terminationHooks += sender
|
terminationHooks += sender
|
||||||
|
|
@ -426,7 +445,7 @@ class LocalActorRefProvider(
|
||||||
}
|
}
|
||||||
|
|
||||||
def stopWhenAllTerminationHooksDone(): Unit = if (terminationHooks.isEmpty) {
|
def stopWhenAllTerminationHooksDone(): Unit = if (terminationHooks.isEmpty) {
|
||||||
if (isSystem) eventStream.stopDefaultLoggers()
|
eventStream.stopDefaultLoggers()
|
||||||
context.stop(self)
|
context.stop(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,7 +503,7 @@ class LocalActorRefProvider(
|
||||||
protected def systemGuardianStrategy: SupervisorStrategy = SupervisorStrategy.defaultStrategy
|
protected def systemGuardianStrategy: SupervisorStrategy = SupervisorStrategy.defaultStrategy
|
||||||
|
|
||||||
lazy val rootGuardian: LocalActorRef =
|
lazy val rootGuardian: LocalActorRef =
|
||||||
new LocalActorRef(system, Props(new Guardian(rootGuardianStrategy, isSystem = false)), theOneWhoWalksTheBubblesOfSpaceTime, rootPath) {
|
new LocalActorRef(system, Props(new Guardian(rootGuardianStrategy)), theOneWhoWalksTheBubblesOfSpaceTime, rootPath) {
|
||||||
override def getParent: InternalActorRef = this
|
override def getParent: InternalActorRef = this
|
||||||
override def getSingleChild(name: String): InternalActorRef = name match {
|
override def getSingleChild(name: String): InternalActorRef = name match {
|
||||||
case "temp" ⇒ tempContainer
|
case "temp" ⇒ tempContainer
|
||||||
|
|
@ -496,7 +515,7 @@ class LocalActorRefProvider(
|
||||||
lazy val guardian: LocalActorRef = {
|
lazy val guardian: LocalActorRef = {
|
||||||
val cell = rootGuardian.underlying
|
val cell = rootGuardian.underlying
|
||||||
cell.reserveChild("user")
|
cell.reserveChild("user")
|
||||||
val ref = new LocalActorRef(system, Props(new Guardian(guardianStrategy, isSystem = false)), rootGuardian, rootPath / "user")
|
val ref = new LocalActorRef(system, Props(new Guardian(guardianStrategy)), rootGuardian, rootPath / "user")
|
||||||
cell.initChild(ref)
|
cell.initChild(ref)
|
||||||
ref
|
ref
|
||||||
}
|
}
|
||||||
|
|
@ -504,7 +523,7 @@ class LocalActorRefProvider(
|
||||||
lazy val systemGuardian: LocalActorRef = {
|
lazy val systemGuardian: LocalActorRef = {
|
||||||
val cell = rootGuardian.underlying
|
val cell = rootGuardian.underlying
|
||||||
cell.reserveChild("system")
|
cell.reserveChild("system")
|
||||||
val ref = new LocalActorRef(system, Props(new Guardian(systemGuardianStrategy, isSystem = true)), rootGuardian, rootPath / "system")
|
val ref = new LocalActorRef(system, Props(new SystemGuardian(systemGuardianStrategy)), rootGuardian, rootPath / "system")
|
||||||
cell.initChild(ref)
|
cell.initChild(ref)
|
||||||
ref
|
ref
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ private[akka] case class DaemonMsgCreate(props: Props, deploy: Deploy, path: Str
|
||||||
private[akka] class RemoteSystemDaemon(system: ActorSystemImpl, _path: ActorPath, _parent: InternalActorRef, _log: LoggingAdapter)
|
private[akka] class RemoteSystemDaemon(system: ActorSystemImpl, _path: ActorPath, _parent: InternalActorRef, _log: LoggingAdapter)
|
||||||
extends VirtualPathContainer(system.provider, _path, _parent, _log) {
|
extends VirtualPathContainer(system.provider, _path, _parent, _log) {
|
||||||
|
|
||||||
import akka.actor.Guardian._
|
import akka.actor.SystemGuardian._
|
||||||
|
|
||||||
private val terminating = new Switch(false)
|
private val terminating = new Switch(false)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue