From e8a5787ef48e265b5e4529703231a81084197828 Mon Sep 17 00:00:00 2001 From: "Andy.Chen" Date: Wed, 3 Jul 2024 14:09:41 +0800 Subject: [PATCH] distinguish between fatal and normal fault --- .../apache/pekko/actor/SupervisorSpec.scala | 31 ++++++++++--------- .../org/apache/pekko/actor/ActorCell.scala | 4 ++- .../pekko/actor/dungeon/FaultHandling.scala | 2 +- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/actor-tests/src/test/scala/org/apache/pekko/actor/SupervisorSpec.scala b/actor-tests/src/test/scala/org/apache/pekko/actor/SupervisorSpec.scala index bf8f6ce7c2d..4c024186df5 100644 --- a/actor-tests/src/test/scala/org/apache/pekko/actor/SupervisorSpec.scala +++ b/actor-tests/src/test/scala/org/apache/pekko/actor/SupervisorSpec.scala @@ -20,6 +20,7 @@ import scala.concurrent.duration._ import com.typesafe.config.Config import com.typesafe.config.ConfigFactory + import language.postfixOps import org.scalatest.BeforeAndAfterEach @@ -543,25 +544,25 @@ class SupervisorSpec "supervise exceptions on child actor initialize" in { val parent = system.actorOf(Props(new Actor { - val cnt: AtomicInteger = new AtomicInteger(0) - var childRef: ActorRef = _ + val cnt: AtomicInteger = new AtomicInteger(0) + var childRef: ActorRef = _ - override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy() { - case _: ActorInitializationException => SupervisorStrategy.Restart - case _ => SupervisorStrategy.Stop - } + override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy() { + case _: ActorInitializationException => SupervisorStrategy.Restart + case _ => SupervisorStrategy.Stop + } - override def preStart(): Unit = { - childRef = context.actorOf(Props(new Child(cnt.getAndIncrement()))) - } + override def preStart(): Unit = { + childRef = context.actorOf(Props(new Child(cnt.getAndIncrement())), "child") + } - def childAlive(): Boolean = childRef != null && !childRef.isTerminated + def childAlive(): Boolean = childRef != null && !childRef.isTerminated - def receive = { - case msg if msg == PingMessage && childAlive() => - sender() ! PongMessage - } - })) + def receive = { + case msg if msg == PingMessage && childAlive() => + sender() ! PongMessage + } + }), "parent") val probe = TestProbe() probe.send(parent, PingMessage) diff --git a/actor/src/main/scala/org/apache/pekko/actor/ActorCell.scala b/actor/src/main/scala/org/apache/pekko/actor/ActorCell.scala index 166d771ddcb..a54193f85ac 100644 --- a/actor/src/main/scala/org/apache/pekko/actor/ActorCell.scala +++ b/actor/src/main/scala/org/apache/pekko/actor/ActorCell.scala @@ -643,7 +643,6 @@ private[pekko] class ActorCell( def failActor(): Unit = if (_actor != null) { clearActorFields(actor, recreate = false) - setFailed(actor.self) _actor = null // ensure that we know that we failed during creation } @@ -658,6 +657,7 @@ private[pekko] class ActorCell( } catch { case e: InterruptedException => failActor() + setFailedFatally() Thread.currentThread().interrupt() throw ActorInitializationException(self, "interruption during creation", e) case NonFatal(e) => @@ -717,6 +717,8 @@ private[pekko] class ActorCell( final protected def clearActorFields(actorInstance: Actor, recreate: Boolean): Unit = { currentMessage = null behaviorStack = emptyBehaviorStack + if (recreate) setFailed(actorInstance.self) + else setFailed(system.deadLetters) } final protected def clearFieldsForTermination(): Unit = { unstashAll() diff --git a/actor/src/main/scala/org/apache/pekko/actor/dungeon/FaultHandling.scala b/actor/src/main/scala/org/apache/pekko/actor/dungeon/FaultHandling.scala index 0135183c8c8..2c278eef5c9 100644 --- a/actor/src/main/scala/org/apache/pekko/actor/dungeon/FaultHandling.scala +++ b/actor/src/main/scala/org/apache/pekko/actor/dungeon/FaultHandling.scala @@ -296,8 +296,8 @@ private[pekko] trait FaultHandling { this: ActorCell => publish(Error(e, self.path.toString, clazz(freshActor), "restarting " + child)) }) } catch handleNonFatalOrInterruptedException { e => - setFailedFatally() clearActorFields(actor, recreate = false) // in order to prevent preRestart() from happening again + setFailedFatally() handleInvokeFailure(survivors, PostRestartException(self, e, cause)) } }