Remote DeathWatch (2): make it work

- introduce EmptyLocalActorRef, which is returned for unsuccessful
  look-ups of local scope
- this fixes the problem that actors—after their death—can still be
  looked up without losing their identity; otherwise behave like
  DeadLetterActorRef
- adapt tests accordingly
- make DeathWatchSpec reusable and build remote test from it
- remove several unused imports of LocalActorRef
- use LocalRef/RemoteRef in pattern matches where applicable: these are
  marker traits for a ref’s scope; InternalActorRef mandates a scope as
  per its self-type
This commit is contained in:
Roland 2011-12-29 16:27:32 +01:00
parent b15f4a2f1a
commit 0ed6a67e08
16 changed files with 147 additions and 59 deletions

View file

@ -31,7 +31,6 @@ class RemoteActorRefProvider(
val remoteSettings = new RemoteSettings(settings.config, systemName)
def deathWatch = local.deathWatch
def rootGuardian = local.rootGuardian
def guardian = local.guardian
def systemGuardian = local.systemGuardian
@ -49,6 +48,8 @@ class RemoteActorRefProvider(
private val local = new LocalActorRefProvider(systemName, settings, eventStream, scheduler, _deadLetters, rootPath, deployer)
val deathWatch = new RemoteDeathWatch(local.deathWatch, this)
def init(system: ActorSystemImpl) {
local.init(system)
remote.init(system, this)
@ -150,6 +151,10 @@ class RemoteActorRefProvider(
}
}
trait RemoteRef extends ActorRefScope {
final def isLocal = false
}
/**
* Remote ActorRef that is used when referencing the Actor on a different node than its "home" node.
* This reference is network-aware (remembers its origin) and immutable.
@ -160,7 +165,7 @@ private[akka] class RemoteActorRef private[akka] (
val path: ActorPath,
val getParent: InternalActorRef,
loader: Option[ClassLoader])
extends InternalActorRef {
extends InternalActorRef with RemoteRef {
def getChild(name: Iterator[String]): InternalActorRef = {
val s = name.toStream
@ -206,11 +211,11 @@ private[akka] class RemoteActorRef private[akka] (
class RemoteDeathWatch(val local: LocalDeathWatch, val provider: RemoteActorRefProvider) extends DeathWatch {
def subscribe(watcher: ActorRef, watched: ActorRef): Boolean = watched match {
case r: RemoteActorRef
case r: RemoteRef
val ret = local.subscribe(watcher, watched)
provider.actorFor(r.path.root / "remote") ! DaemonMsgWatch(watcher, watched)
ret
case l: LocalActorRef
case l: LocalRef
local.subscribe(watcher, watched)
case _
provider.log.error("unknown ActorRef type {} as DeathWatch target", watched.getClass)