diff --git a/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/GracefulStopDocTest.java b/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/GracefulStopDocTest.java index 22e78cd539..9676d4c6c2 100644 --- a/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/GracefulStopDocTest.java +++ b/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/GracefulStopDocTest.java @@ -67,9 +67,9 @@ interface GracefulStopDocTest { private Behavior onGracefulShutdown() { getContext().getSystem().log().info("Initiating graceful shutdown..."); - // perform graceful stop, executing cleanup before final system termination - // behavior executing cleanup is passed as a parameter to Actor.stopped - return Behaviors.stopped(() -> getContext().getSystem().log().info("Cleanup!")); + // Here it can perform graceful stop (possibly asynchronous) and when completed + // return `Behaviors.stopped()` here or after receiving another message. + return Behaviors.stopped(); } private Behavior onPostStop() { @@ -80,8 +80,6 @@ interface GracefulStopDocTest { // #master-actor public static void main(String[] args) throws Exception { - // #graceful-shutdown - final ActorSystem system = ActorSystem.create(MasterControlProgram.create(), "B6700"); @@ -94,7 +92,6 @@ interface GracefulStopDocTest { system.tell(MasterControlProgram.GracefulShutdown.INSTANCE); system.getWhenTerminated().toCompletableFuture().get(3, TimeUnit.SECONDS); - // #graceful-shutdown } // #worker-actor diff --git a/akka-actor-typed-tests/src/test/scala/docs/akka/typed/GracefulStopDocSpec.scala b/akka-actor-typed-tests/src/test/scala/docs/akka/typed/GracefulStopDocSpec.scala index a18d6750d9..9d38053a19 100644 --- a/akka-actor-typed-tests/src/test/scala/docs/akka/typed/GracefulStopDocSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/docs/akka/typed/GracefulStopDocSpec.scala @@ -13,7 +13,6 @@ import akka.actor.typed.{ ActorSystem, PostStop } import akka.actor.testkit.typed.scaladsl.LogCapturing import akka.actor.typed.ActorRef -import org.slf4j.Logger import scala.concurrent.duration._ import scala.concurrent.Await import org.scalatest.wordspec.AnyWordSpecLike @@ -30,9 +29,6 @@ object GracefulStopDocSpec { final case class SpawnJob(name: String) extends Command case object GracefulShutdown extends Command - // Predefined cleanup operation - def cleanup(log: Logger): Unit = log.info("Cleaning up!") - def apply(): Behavior[Command] = { Behaviors .receive[Command] { (context, message) => @@ -43,11 +39,9 @@ object GracefulStopDocSpec { Behaviors.same case GracefulShutdown => context.log.info("Initiating graceful shutdown...") - // perform graceful stop, executing cleanup before final system termination - // behavior executing cleanup is passed as a parameter to Actor.stopped - Behaviors.stopped { () => - cleanup(context.system.log) - } + // Here it can perform graceful stop (possibly asynchronous) and when completed + // return `Behaviors.stopped` here or after receiving another message. + Behaviors.stopped } } .receiveSignal { @@ -158,8 +152,6 @@ class GracefulStopDocSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike } "gracefully stop workers and master" in { - //#graceful-shutdown - import MasterControlProgram._ val system: ActorSystem[Command] = ActorSystem(MasterControlProgram(), "B7700") @@ -175,7 +167,6 @@ class GracefulStopDocSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike Thread.sleep(100) Await.result(system.whenTerminated, 3.seconds) - //#graceful-shutdown } } } diff --git a/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/Behaviors.scala b/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/Behaviors.scala index 301b492ef1..09aefb8b8d 100644 --- a/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/Behaviors.scala +++ b/akka-actor-typed/src/main/scala/akka/actor/typed/javadsl/Behaviors.scala @@ -89,6 +89,9 @@ object Behaviors { * The `PostStop` signal that results from stopping this actor will first be passed to the * current behavior and then the provided `postStop` callback will be invoked. * All other messages and signals will effectively be ignored. + * + * An example of when the callback can be useful compared to the `PostStop` signal + * if you want to send a reply to the message that initiated a graceful stop. */ def stopped[T](postStop: Effect): Behavior[T] = BehaviorImpl.stopped(postStop.apply _) diff --git a/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/Behaviors.scala b/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/Behaviors.scala index df7ffa8b0b..428ef56085 100644 --- a/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/Behaviors.scala +++ b/akka-actor-typed/src/main/scala/akka/actor/typed/scaladsl/Behaviors.scala @@ -73,6 +73,9 @@ object Behaviors { * The `PostStop` signal that results from stopping this actor will first be passed to the * current behavior and then the provided `postStop` callback will be invoked. * All other messages and signals will effectively be ignored. + * + * An example of when the callback can be useful compared to the `PostStop` signal + * if you want to send a reply to the message that initiated a graceful stop. */ def stopped[T](postStop: () => Unit): Behavior[T] = BehaviorImpl.stopped(postStop) diff --git a/akka-docs/src/main/paradox/typed/actor-lifecycle.md b/akka-docs/src/main/paradox/typed/actor-lifecycle.md index 9a37546bbb..b52f9ebb4d 100644 --- a/akka-docs/src/main/paradox/typed/actor-lifecycle.md +++ b/akka-docs/src/main/paradox/typed/actor-lifecycle.md @@ -165,8 +165,6 @@ A child actor can be forced to stop after it finishes processing its current mes All child actors will be stopped when their parent is stopped. When an actor is stopped, it receives the `PostStop` signal that can be used for cleaning up resources. -A callback function may be specified as parameter to `Behaviors.stopped` to handle the `PostStop` signal -when stopping gracefully. This allows to apply different actions when it is stopped abruptly. Here is an illustrating example: @@ -175,7 +173,6 @@ Scala #imports #master-actor #worker-actor - #graceful-shutdown } Java @@ -183,7 +180,6 @@ Java #imports #master-actor #worker-actor - #graceful-shutdown } When cleaning up resources from `PostStop` you should also consider doing the same for the `PreRestart` signal,