* need for the callback variant should be a rare so we should not confuse the users with it in this example * mention of callback in api docs should be enough
This commit is contained in:
parent
592b1d10ad
commit
8d25ca2012
5 changed files with 12 additions and 22 deletions
|
|
@ -67,9 +67,9 @@ interface GracefulStopDocTest {
|
||||||
private Behavior<Command> onGracefulShutdown() {
|
private Behavior<Command> onGracefulShutdown() {
|
||||||
getContext().getSystem().log().info("Initiating graceful shutdown...");
|
getContext().getSystem().log().info("Initiating graceful shutdown...");
|
||||||
|
|
||||||
// perform graceful stop, executing cleanup before final system termination
|
// Here it can perform graceful stop (possibly asynchronous) and when completed
|
||||||
// behavior executing cleanup is passed as a parameter to Actor.stopped
|
// return `Behaviors.stopped()` here or after receiving another message.
|
||||||
return Behaviors.stopped(() -> getContext().getSystem().log().info("Cleanup!"));
|
return Behaviors.stopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Behavior<Command> onPostStop() {
|
private Behavior<Command> onPostStop() {
|
||||||
|
|
@ -80,8 +80,6 @@ interface GracefulStopDocTest {
|
||||||
// #master-actor
|
// #master-actor
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// #graceful-shutdown
|
|
||||||
|
|
||||||
final ActorSystem<MasterControlProgram.Command> system =
|
final ActorSystem<MasterControlProgram.Command> system =
|
||||||
ActorSystem.create(MasterControlProgram.create(), "B6700");
|
ActorSystem.create(MasterControlProgram.create(), "B6700");
|
||||||
|
|
||||||
|
|
@ -94,7 +92,6 @@ interface GracefulStopDocTest {
|
||||||
system.tell(MasterControlProgram.GracefulShutdown.INSTANCE);
|
system.tell(MasterControlProgram.GracefulShutdown.INSTANCE);
|
||||||
|
|
||||||
system.getWhenTerminated().toCompletableFuture().get(3, TimeUnit.SECONDS);
|
system.getWhenTerminated().toCompletableFuture().get(3, TimeUnit.SECONDS);
|
||||||
// #graceful-shutdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #worker-actor
|
// #worker-actor
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import akka.actor.typed.{ ActorSystem, PostStop }
|
||||||
|
|
||||||
import akka.actor.testkit.typed.scaladsl.LogCapturing
|
import akka.actor.testkit.typed.scaladsl.LogCapturing
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
import org.slf4j.Logger
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.concurrent.Await
|
import scala.concurrent.Await
|
||||||
import org.scalatest.wordspec.AnyWordSpecLike
|
import org.scalatest.wordspec.AnyWordSpecLike
|
||||||
|
|
@ -30,9 +29,6 @@ object GracefulStopDocSpec {
|
||||||
final case class SpawnJob(name: String) extends Command
|
final case class SpawnJob(name: String) extends Command
|
||||||
case object GracefulShutdown extends Command
|
case object GracefulShutdown extends Command
|
||||||
|
|
||||||
// Predefined cleanup operation
|
|
||||||
def cleanup(log: Logger): Unit = log.info("Cleaning up!")
|
|
||||||
|
|
||||||
def apply(): Behavior[Command] = {
|
def apply(): Behavior[Command] = {
|
||||||
Behaviors
|
Behaviors
|
||||||
.receive[Command] { (context, message) =>
|
.receive[Command] { (context, message) =>
|
||||||
|
|
@ -43,11 +39,9 @@ object GracefulStopDocSpec {
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
case GracefulShutdown =>
|
case GracefulShutdown =>
|
||||||
context.log.info("Initiating graceful shutdown...")
|
context.log.info("Initiating graceful shutdown...")
|
||||||
// perform graceful stop, executing cleanup before final system termination
|
// Here it can perform graceful stop (possibly asynchronous) and when completed
|
||||||
// behavior executing cleanup is passed as a parameter to Actor.stopped
|
// return `Behaviors.stopped` here or after receiving another message.
|
||||||
Behaviors.stopped { () =>
|
Behaviors.stopped
|
||||||
cleanup(context.system.log)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.receiveSignal {
|
.receiveSignal {
|
||||||
|
|
@ -158,8 +152,6 @@ class GracefulStopDocSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike
|
||||||
}
|
}
|
||||||
|
|
||||||
"gracefully stop workers and master" in {
|
"gracefully stop workers and master" in {
|
||||||
//#graceful-shutdown
|
|
||||||
|
|
||||||
import MasterControlProgram._
|
import MasterControlProgram._
|
||||||
|
|
||||||
val system: ActorSystem[Command] = ActorSystem(MasterControlProgram(), "B7700")
|
val system: ActorSystem[Command] = ActorSystem(MasterControlProgram(), "B7700")
|
||||||
|
|
@ -175,7 +167,6 @@ class GracefulStopDocSpec extends ScalaTestWithActorTestKit with AnyWordSpecLike
|
||||||
Thread.sleep(100)
|
Thread.sleep(100)
|
||||||
|
|
||||||
Await.result(system.whenTerminated, 3.seconds)
|
Await.result(system.whenTerminated, 3.seconds)
|
||||||
//#graceful-shutdown
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,9 @@ object Behaviors {
|
||||||
* The `PostStop` signal that results from stopping this actor will first be passed to the
|
* 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.
|
* current behavior and then the provided `postStop` callback will be invoked.
|
||||||
* All other messages and signals will effectively be ignored.
|
* 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 _)
|
def stopped[T](postStop: Effect): Behavior[T] = BehaviorImpl.stopped(postStop.apply _)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,9 @@ object Behaviors {
|
||||||
* The `PostStop` signal that results from stopping this actor will first be passed to the
|
* 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.
|
* current behavior and then the provided `postStop` callback will be invoked.
|
||||||
* All other messages and signals will effectively be ignored.
|
* 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)
|
def stopped[T](postStop: () => Unit): Behavior[T] = BehaviorImpl.stopped(postStop)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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.
|
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:
|
Here is an illustrating example:
|
||||||
|
|
||||||
|
|
@ -175,7 +173,6 @@ Scala
|
||||||
#imports
|
#imports
|
||||||
#master-actor
|
#master-actor
|
||||||
#worker-actor
|
#worker-actor
|
||||||
#graceful-shutdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Java
|
Java
|
||||||
|
|
@ -183,7 +180,6 @@ Java
|
||||||
#imports
|
#imports
|
||||||
#master-actor
|
#master-actor
|
||||||
#worker-actor
|
#worker-actor
|
||||||
#graceful-shutdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
When cleaning up resources from `PostStop` you should also consider doing the same for the `PreRestart` signal,
|
When cleaning up resources from `PostStop` you should also consider doing the same for the `PreRestart` signal,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue