Don't rethrow InterruptedException when handling failures in the dungeon. See #3006
This commit is contained in:
parent
1a3113c867
commit
1bc11d1365
3 changed files with 27 additions and 21 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue