Akka技术问题:注册终止回调后未收到TerminationCallbacks
Got it, let's break down why your ActorSystem termination callbacks aren't triggering and walk through fixes tailored to your code.
1. Your ActorSystem Isn't Actually Being Terminated
The biggest issue here is that stopping a child actor doesn't terminate the entire ActorSystem. In your code, when the ChildActor throws an OutOfMemoryError, the parent's supervisor strategy stops the child—but the parent actor (and the rest of the ActorSystem) remains active. Termination callbacks only fire when you explicitly shut down the ActorSystem, or when all top-level guardian actors are stopped and no other active actors are left.
Fix: Trigger ActorSystem Termination When Needed
Update your ParentActor to watch the child actor, then call system.terminate() once the child is terminated. Here's the adjusted code:
class ParentActor extends Actor { // Create and watch the child actor to monitor its termination val childActor = context.actorOf(Props[ChildActor], "child-actor") context.watch(childActor) override val supervisorStrategy = OneForOneStrategy() { case _: OutOfMemoryError => Stop case _: Exception => Restart // Fill in your preferred handling for other exceptions } override def receive: Receive = { case msg => childActor.forward(msg) // Pass messages to the child case Terminated(actor) if actor == childActor => // Trigger ActorSystem shutdown once the child stops context.system.terminate() } }
2. Verify Callback Registration Timing
Make sure you register your termination callback before any operations that could trigger system shutdown. If you register the callback after calling system.terminate(), or after the system has already started shutting down, you won't receive the notification.
Correct Registration Example:
val system = ActorSystem("MyActorSystem") // Register callback FIRST system.registerOnTermination(() => { println("ActorSystem has terminated successfully!") // Add your cleanup logic here }) // Then create actors and start processing messages val parentActor = system.actorOf(Props[ParentActor], "parent-actor")
3. Fix Incomplete Supervisor Strategy
Your code snippet cuts off at case _: Except...—make sure you complete this with valid exception handling (e.g., Exception instead of Except) and that the strategy is properly defined. A broken supervisor strategy might not correctly stop the child actor, which would prevent the termination flow from triggering at all.
Testing the Flow
- Start the ActorSystem and register your callback.
- Send a
ChildActor.Msgto the parent actor. - The child throws
OutOfMemoryError, the parent stops it via the supervisor strategy. - The parent receives the
Terminatedmessage from the watched child. - The parent calls
system.terminate(), which triggers your registered callback.
内容的提问来源于stack exchange,提问作者ayush

