incorporate review comments
- add two missing @volatiles - add quite some comments - refactor provider.actorOf to always take a path for the child, not only a name
This commit is contained in:
parent
d4a764cfd9
commit
09aadcb60d
4 changed files with 77 additions and 41 deletions
|
|
@ -223,7 +223,7 @@ private[akka] class ActorCell(
|
|||
final var childrenRefs: TreeMap[String, ChildRestartStats] = emptyChildrenRefs
|
||||
|
||||
private def _actorOf(props: Props, name: String): ActorRef = {
|
||||
val actor = provider.actorOf(systemImpl, props, guardian, name, false)
|
||||
val actor = provider.actorOf(systemImpl, props, self, self.path / name, false)
|
||||
childrenRefs = childrenRefs.updated(name, ChildRestartStats(actor))
|
||||
actor
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ trait ActorRefProvider {
|
|||
* in case of remote supervision). If systemService is true, deployment is
|
||||
* bypassed (local-only).
|
||||
*/
|
||||
def actorOf(system: ActorSystemImpl, props: Props, supervisor: InternalActorRef, name: String, systemService: Boolean = false): InternalActorRef
|
||||
def actorOf(system: ActorSystemImpl, props: Props, supervisor: InternalActorRef, path: ActorPath, systemService: Boolean): InternalActorRef
|
||||
|
||||
/**
|
||||
* Create actor reference for a specified local or remote path. If no such
|
||||
|
|
@ -408,30 +408,32 @@ class LocalActorRefProvider(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Guardians can be asked by ActorSystem to create children, i.e. top-level
|
||||
* actors. Therefore these need to answer to these requests, forwarding any
|
||||
* exceptions which might have occurred.
|
||||
*/
|
||||
private class Guardian extends Actor {
|
||||
def receive = {
|
||||
case Terminated(_) ⇒ context.self.stop()
|
||||
case CreateChild(child, name) ⇒ sender ! (try context.actorOf(child, name) catch {
|
||||
case e: Exception ⇒ e
|
||||
})
|
||||
case CreateRandomNameChild(child) ⇒ sender ! (try context.actorOf(child) catch {
|
||||
case e: Exception ⇒ e
|
||||
})
|
||||
case CreateChild(child, name) ⇒ sender ! (try context.actorOf(child, name) catch { case e: Exception ⇒ e })
|
||||
case CreateRandomNameChild(child) ⇒ sender ! (try context.actorOf(child) catch { case e: Exception ⇒ e })
|
||||
case m ⇒ deadLetters ! DeadLetter(m, sender, self)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Guardians can be asked by ActorSystem to create children, i.e. top-level
|
||||
* actors. Therefore these need to answer to these requests, forwarding any
|
||||
* exceptions which might have occurred.
|
||||
*/
|
||||
private class SystemGuardian extends Actor {
|
||||
def receive = {
|
||||
case Terminated(_) ⇒
|
||||
eventStream.stopDefaultLoggers()
|
||||
context.self.stop()
|
||||
case CreateChild(child, name) ⇒ sender ! (try context.actorOf(child, name) catch {
|
||||
case e: Exception ⇒ e
|
||||
})
|
||||
case CreateRandomNameChild(child) ⇒ sender ! (try context.actorOf(child) catch {
|
||||
case e: Exception ⇒ e
|
||||
})
|
||||
case CreateChild(child, name) ⇒ sender ! (try context.actorOf(child, name) catch { case e: Exception ⇒ e })
|
||||
case CreateRandomNameChild(child) ⇒ sender ! (try context.actorOf(child) catch { case e: Exception ⇒ e })
|
||||
case m ⇒ deadLetters ! DeadLetter(m, sender, self)
|
||||
}
|
||||
}
|
||||
|
|
@ -463,10 +465,20 @@ class LocalActorRefProvider(
|
|||
@volatile
|
||||
private var extraNames: Map[String, InternalActorRef] = Map()
|
||||
|
||||
lazy val rootGuardian: InternalActorRef = new LocalActorRef(system, guardianProps, theOneWhoWalksTheBubblesOfSpaceTime, rootPath, true) {
|
||||
/**
|
||||
* Higher-level providers (or extensions) might want to register new synthetic
|
||||
* top-level paths for doing special stuff. This is the way to do just that.
|
||||
* Just be careful to complete all this before ActorSystem.start() finishes,
|
||||
* or before you start your own auto-spawned actors.
|
||||
*/
|
||||
def registerExtraNames(_extras: Map[String, InternalActorRef]): Unit = extraNames ++= _extras
|
||||
|
||||
lazy val rootGuardian: InternalActorRef =
|
||||
new LocalActorRef(system, guardianProps, theOneWhoWalksTheBubblesOfSpaceTime, rootPath, true) {
|
||||
object Extra {
|
||||
def unapply(s: String): Option[InternalActorRef] = extraNames.get(s)
|
||||
}
|
||||
|
||||
override def getParent: InternalActorRef = this
|
||||
|
||||
override def getSingleChild(name: String): InternalActorRef = {
|
||||
|
|
@ -478,9 +490,11 @@ class LocalActorRefProvider(
|
|||
}
|
||||
}
|
||||
|
||||
lazy val guardian: InternalActorRef = actorOf(system, guardianProps, rootGuardian, "user", true)
|
||||
lazy val guardian: InternalActorRef =
|
||||
actorOf(system, guardianProps, rootGuardian, rootPath / "user", true)
|
||||
|
||||
lazy val systemGuardian: InternalActorRef = actorOf(system, guardianProps.withCreator(new SystemGuardian), rootGuardian, "system", true)
|
||||
lazy val systemGuardian: InternalActorRef =
|
||||
actorOf(system, guardianProps.withCreator(new SystemGuardian), rootGuardian, rootPath / "system", true)
|
||||
|
||||
lazy val tempContainer = new VirtualPathContainer(tempNode, rootGuardian, log)
|
||||
|
||||
|
|
@ -494,8 +508,6 @@ class LocalActorRefProvider(
|
|||
eventStream.startDefaultLoggers(_system)
|
||||
}
|
||||
|
||||
def registerExtraNames(_extras: Map[String, InternalActorRef]): Unit = extraNames ++= _extras
|
||||
|
||||
def actorFor(ref: InternalActorRef, path: String): InternalActorRef = path match {
|
||||
case RelativeActorPath(elems) ⇒
|
||||
if (elems.isEmpty) deadLetters
|
||||
|
|
@ -516,9 +528,7 @@ class LocalActorRefProvider(
|
|||
case x ⇒ x
|
||||
}
|
||||
|
||||
def actorOf(system: ActorSystemImpl, props: Props, supervisor: InternalActorRef, name: String, systemService: Boolean): InternalActorRef = {
|
||||
val path = supervisor.path / name
|
||||
|
||||
def actorOf(system: ActorSystemImpl, props: Props, supervisor: InternalActorRef, path: ActorPath, systemService: Boolean): InternalActorRef = {
|
||||
props.routerConfig match {
|
||||
case NoRouting ⇒ new LocalActorRef(system, props, supervisor, path, systemService) // create a local actor
|
||||
case routedActor ⇒ new RoutedActorRef(system, props.withRouting(adaptFromDeploy(routedActor, path)), supervisor, path)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ class RemoteSystemDaemon(remote: Remote, _path: ActorPath, _parent: InternalActo
|
|||
val subpath = elems.drop(1)
|
||||
val path = remote.remoteDaemon.path / subpath
|
||||
val supervisor = remote.system.actorFor(message.getSupervisor).asInstanceOf[InternalActorRef]
|
||||
val actor = new LocalActorRef(remote.system, Props(creator = actorFactory), supervisor, path, true)
|
||||
val actor = remote.system.provider.actorOf(remote.system, Props(creator = actorFactory), supervisor, path, true)
|
||||
addChild(subpath.mkString("/"), actor)
|
||||
remote.system.deathWatch.subscribe(this, actor)
|
||||
case _ ⇒
|
||||
|
|
|
|||
|
|
@ -56,8 +56,10 @@ class RemoteActorRefProvider(
|
|||
|
||||
private val local = new LocalActorRefProvider(systemName, settings, eventStream, scheduler, _deadLetters, rootPath, deployer)
|
||||
|
||||
@volatile
|
||||
private var serialization: Serialization = _
|
||||
|
||||
@volatile
|
||||
private var _remote: Remote = _
|
||||
def remote = _remote
|
||||
|
||||
|
|
@ -69,10 +71,34 @@ class RemoteActorRefProvider(
|
|||
terminationFuture.onComplete(_ ⇒ remote.server.shutdown())
|
||||
}
|
||||
|
||||
def actorOf(system: ActorSystemImpl, props: Props, supervisor: InternalActorRef, name: String, systemService: Boolean): InternalActorRef =
|
||||
if (systemService) local.actorOf(system, props, supervisor, name, systemService)
|
||||
def actorOf(system: ActorSystemImpl, props: Props, supervisor: InternalActorRef, path: ActorPath, systemService: Boolean): InternalActorRef =
|
||||
if (systemService) local.actorOf(system, props, supervisor, path, systemService)
|
||||
else {
|
||||
val path = supervisor.path / name
|
||||
|
||||
/*
|
||||
* This needs to deal with “mangled” paths, which are created by remote
|
||||
* deployment, also in this method. The scheme is the following:
|
||||
*
|
||||
* Whenever a remote deployment is found, create a path on that remote
|
||||
* address below “remote”, including the current system’s identification
|
||||
* as “sys@host:port” (typically; it will use whatever the remote
|
||||
* transport uses). This means that on a path up an actor tree each node
|
||||
* change introduces one layer or “remote/sys@host:port/” within the URI.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* akka://sys@home:1234/remote/sys@remote:6667/remote/sys@other:3333/user/a/b/c
|
||||
*
|
||||
* means that the logical parent originates from “sys@other:3333” with
|
||||
* one child (may be “a” or “b”) being deployed on “sys@remote:6667” and
|
||||
* finally either “b” or “c” being created on “sys@home:1234”, where
|
||||
* this whole thing actually resides. Thus, the logical path is
|
||||
* “/user/a/b/c” and the physical path contains all remote placement
|
||||
* information.
|
||||
*
|
||||
* Deployments are always looked up using the logical path, which is the
|
||||
* purpose of the lookupRemotes internal method.
|
||||
*/
|
||||
|
||||
@scala.annotation.tailrec
|
||||
def lookupRemotes(p: Iterable[String]): Option[DeploymentConfig.Deploy] = {
|
||||
|
|
@ -94,14 +120,14 @@ class RemoteActorRefProvider(
|
|||
deployment match {
|
||||
case Some(DeploymentConfig.Deploy(_, _, _, _, RemoteDeploymentConfig.RemoteScope(address))) ⇒
|
||||
|
||||
if (address == rootPath.address) local.actorOf(system, props, supervisor, name)
|
||||
if (address == rootPath.address) local.actorOf(system, props, supervisor, path, false)
|
||||
else {
|
||||
val rpath = RootActorPath(address) / "remote" / rootPath.address.hostPort / path.elements
|
||||
useActorOnNode(rpath, props.creator, supervisor)
|
||||
new RemoteActorRef(this, remote.server, rpath, supervisor, None)
|
||||
}
|
||||
|
||||
case _ ⇒ local.actorOf(system, props, supervisor, name, systemService)
|
||||
case _ ⇒ local.actorOf(system, props, supervisor, path, systemService)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue