Introduce parental supervision, BUT TESTS ARE STILL FAILING

- every actor is now supervised, where the root of the tree is
  app.guardian, which has its supervisor field set to a special ActorRef
  obtained from provider.theOneWhoWalksTheBubblesOfSpaceTime (this name
  is meant to indicate that this ref is outside of the universe, cf.
  Michio Kaku)
- changed all tests to obtain specially supervised children (i.e. not
  top-level) via (supervisor ? Props).as[ActorRef].get
- add private[akka] ScalaActorRef.sendSystemMessage for sending
  Supervise()
- everything routing or remote is broken wrt. supervision, as that was
  not “properly” implemented to begin with, will be tackled after
  app/supervision/eventbus/AkkaSpec are stabilized enough
This commit is contained in:
Roland 2011-10-18 15:39:26 +02:00
parent 25e8eb1422
commit d3837b9fc3
34 changed files with 290 additions and 226 deletions

View file

@ -31,6 +31,8 @@ class RemoteActorRefProvider(val app: AkkaApplication) extends ActorRefProvider
import java.util.concurrent.ConcurrentHashMap
import akka.dispatch.Promise
private[akka] val theOneWhoWalksTheBubblesOfSpaceTime: ActorRef = new UnsupportedActorRef {}
val local = new LocalActorRefProvider(app)
val remote = new Remote(app)
@ -44,10 +46,8 @@ class RemoteActorRefProvider(val app: AkkaApplication) extends ActorRefProvider
def defaultDispatcher = app.dispatcher
def defaultTimeout = app.AkkaConfig.ActorTimeout
def actorOf(props: Props, address: String): ActorRef = actorOf(props, address, false)
def actorOf(props: Props, address: String, systemService: Boolean): ActorRef =
if (systemService) local.actorOf(props, address, systemService)
def actorOf(props: Props, supervisor: ActorRef, address: String, systemService: Boolean): ActorRef =
if (systemService) local.actorOf(props, supervisor, address, systemService)
else {
val newFuture = Promise[ActorRef](5000)(defaultDispatcher) // FIXME is this proper timeout?
@ -71,7 +71,7 @@ class RemoteActorRefProvider(val app: AkkaApplication) extends ActorRefProvider
if (isReplicaNode) {
// we are on one of the replica node for this remote actor
new LocalActorRef(app, props, address, false)
new LocalActorRef(app, props, supervisor, address, false)
} else {
// we are on the single "reference" node uses the remote actors on the replica nodes
@ -115,10 +115,10 @@ class RemoteActorRefProvider(val app: AkkaApplication) extends ActorRefProvider
connections.keys foreach { useActorOnNode(_, address, props.creator) }
actorOf(RoutedProps(routerFactory = routerFactory, connectionManager = connectionManager), address)
actorOf(RoutedProps(routerFactory = routerFactory, connectionManager = connectionManager), supervisor, address)
}
case deploy local.actorOf(props, address, systemService)
case deploy local.actorOf(props, supervisor, address, systemService)
}
} catch {
case e: Exception
@ -139,7 +139,8 @@ class RemoteActorRefProvider(val app: AkkaApplication) extends ActorRefProvider
/**
* Copied from LocalActorRefProvider...
*/
def actorOf(props: RoutedProps, address: String): ActorRef = {
// FIXME: implement supervision
def actorOf(props: RoutedProps, supervisor: ActorRef, address: String): ActorRef = {
if (props.connectionManager.isEmpty) throw new ConfigurationException("RoutedProps used for creating actor [" + address + "] has zero connections configured; can't create a router")
new RoutedActorRef(props, address)
}
@ -244,6 +245,8 @@ private[akka] case class RemoteActorRef private[akka] (
def isShutdown: Boolean = !running
protected[akka] def sendSystemMessage(message: SystemMessage): Unit = unsupported
def postMessageToMailbox(message: Any, channel: UntypedChannel) {
val chSender = if (channel.isInstanceOf[ActorRef]) Some(channel.asInstanceOf[ActorRef]) else None
remote.send[Any](message, chSender, None, remoteAddress, true, this, loader)