Don't rethrow InterruptedException when handling failures in the dungeon. See #3006

This commit is contained in:
Björn Antonsson 2013-02-11 12:18:57 +01:00
parent 1a3113c867
commit 1bc11d1365
3 changed files with 27 additions and 21 deletions

View file

@ -471,7 +471,13 @@ private[akka] class ActorCell(
}
}
protected def create(uid: Int): Unit =
protected def create(uid: Int): Unit = {
def clearOutActorIfNonNull(): Unit = {
if (actor != null) {
clearActorFields(actor)
actor = null // ensure that we know that we failed during creation
}
}
try {
this.uid = uid
val created = newActor()
@ -480,11 +486,12 @@ private[akka] class ActorCell(
checkReceiveTimeout
if (system.settings.DebugLifecycle) publish(Debug(self.path.toString, clazz(created), "started (" + created + ")"))
} catch {
case e: InterruptedException
clearOutActorIfNonNull()
Thread.currentThread().interrupt()
throw ActorInitializationException(self, "interruption during creation", e)
case NonFatal(e)
if (actor != null) {
clearActorFields(actor)
actor = null // ensure that we know that we failed during creation
}
clearOutActorIfNonNull()
e match {
case i: InstantiationException throw ActorInitializationException(self,
"""exception during creation, this problem is likely to occur because the class of the Actor you tried to create is either,
@ -494,6 +501,7 @@ private[akka] class ActorCell(
case x throw ActorInitializationException(self, "exception during creation", x)
}
}
}
private def supervise(child: ActorRef, async: Boolean, uid: Int): Unit =
if (!isTerminating) {

View file

@ -185,10 +185,12 @@ private[akka] trait Children { this: ActorCell ⇒
cell.provider.actorOf(cell.systemImpl, props, cell.self, cell.self.path / name,
systemService = systemService, deploy = None, lookupDeploy = true, async = async)
} catch {
case e @ (_: InterruptedException | NonFatal(_))
case e: InterruptedException
unreserveChild(name)
Thread.interrupted() // clear interrupted flag before throwing according to java convention
throw e
case NonFatal(e)
unreserveChild(name)
if (e.isInstanceOf[InterruptedException])
Thread.interrupted() // clear interrupted flag before throwing according to java convention
throw e
}
// mailbox==null during RoutedActorCell constructor, where suspends are queued otherwise

View file

@ -174,20 +174,16 @@ private[akka] trait FaultHandling { this: ActorCell ⇒
case _ setFailed(self); Set.empty
}
suspendChildren(exceptFor = skip ++ childrenNotToSuspend)
// tell supervisor
t match { // Wrap InterruptedExceptions and, clear the flag and rethrow
case _: InterruptedException
parent.tell(Failed(new ActorInterruptedException(t), uid), self)
Thread.interrupted() // clear interrupted flag before throwing according to java convention
throw t
case _ parent.tell(Failed(t, uid), self)
t match {
// tell supervisor
case _: InterruptedException parent.tell(Failed(new ActorInterruptedException(t), uid), self)
case _ parent.tell(Failed(t, uid), self)
}
} catch {
case NonFatal(e)
publish(Error(e, self.path.toString, clazz(actor),
"emergency stop: exception in failure handling for " + t.getClass + Logging.stackTraceFor(t)))
try children foreach stop
finally finishTerminate()
} catch handleNonFatalOrInterruptedException { e
publish(Error(e, self.path.toString, clazz(actor),
"emergency stop: exception in failure handling for " + t.getClass + Logging.stackTraceFor(t)))
try children foreach stop
finally finishTerminate()
}
}