Actor 生命周期

    一个 Actor 可以创建或生成任意数量的子 Actor,而子 Actor 又可以生成自己的子 Actor,从而形成一个 Actor 层次。「ActorSystem」承载层次结构,并且在层次结构的顶部只能有一个根 Actor。一个子 Actor 的生命周期是与其父 Actor 联系在一起的,一个子 Actor 可以在任何时候停止自己或被停止,但永远不能比父 Actor 活得更久。

    根 Actor,也称为守护者 Actor,与ActorSystem一起创建。发送到 Actor 系统的消息被定向到根 Actor。根 Actor 是由用于创建ActorSystem的行为定义的,在下面的示例中名为HelloWorldMain.main

    1. final ActorSystem<HelloWorldMain.Start> system =
    2. ActorSystem.create(HelloWorldMain.main, "hello");
    3. system.tell(new HelloWorldMain.Start("World"));
    4. system.tell(new HelloWorldMain.Start("Akka"));

    子 Actor 是由「」的“繁殖”产生的。在下面的示例中,当根 Actor 启动时,它生成一个由行为HelloWorld.greeter描述的子 Actor。此外,当根 Actor 收到Start消息时,它将创建由行为HelloWorldBot.bot定义的子 Actor:

    要在生成 Actor 时指定调度器,请使用「DispatcherSelector」。如果未指定,则 Actor 将使用默认调度器,有关详细信息,请参阅「」。

    1. public static final Behavior<Start> main =
    2. Behaviors.setup(
    3. context -> {
    4. final String dispatcherPath = "akka.actor.default-blocking-io-dispatcher";
    5. Props props = DispatcherSelector.fromConfig(dispatcherPath);
    6. final ActorRef<HelloWorld.Greet> greeter =
    7. context.spawn(HelloWorld.greeter, "greeter", props);
    8. return Behaviors.receiveMessage(
    9. message -> {
    10. context.spawn(HelloWorldBot.bot(0, 3), message.name);
    11. greeter.tell(new HelloWorld.Greet(message.name, replyTo));
    12. return Behaviors.same();
    13. });
    14. });

    守护者 Actor 应该负责初始化任务并创建应用程序的初始 Actor,但有时你可能希望从守护者 Actor 的外部生成新的 Actor。例如,每个 HTTP 请求创建一个 Actor。

    这并不难你在行为中的实现,但是由于这是一个常见的模式,因此有一个预定义的消息协议和行为的实现。它可以用作的守护者 Actor,可能与Behaviors.setup结合使用以启动一些初始任务或 Actor。然后,可以通过调用SpawnProtocol.Spawn从外部启动子 Actor,生成到系统的 Actor 引用。使用ask时,这类似于ActorSystem.actorOf如何在非类型化 Actor 中使用,不同之处在于ActorRefCompletionStage返回。

    守护者行为可定义为:

    ActorSystem可以用这种main行为来创建,并生成其他 Actor:

    1. import akka.actor.typed.ActorRef;
    2. import akka.actor.typed.ActorSystem;
    3. import akka.actor.typed.Props;
    4. import akka.actor.typed.javadsl.AskPattern;
    5. import akka.util.Timeout;
    6. final ActorSystem<SpawnProtocol> system = ActorSystem.create(HelloWorldMain.main, "hello");
    7. final Duration timeout = Duration.ofSeconds(3);
    8. CompletionStage<ActorRef<HelloWorld.Greet>> greeter =
    9. AskPattern.ask(
    10. system,
    11. replyTo ->
    12. new SpawnProtocol.Spawn<>(HelloWorld.greeter, "greeter", Props.empty(), replyTo),
    13. timeout,
    14. system.scheduler());
    15. Behaviors.receive(
    16. (context, message) -> {
    17. return Behaviors.stopped();
    18. });
    19. CompletionStage<ActorRef<HelloWorld.Greeted>> greetedReplyTo =
    20. AskPattern.ask(
    21. system,
    22. replyTo -> new SpawnProtocol.Spawn<>(greetedBehavior, "", Props.empty(), replyTo),
    23. timeout,
    24. system.scheduler());
    25. greeter.whenComplete(
    26. (greeterRef, exc) -> {
    27. if (exc == null) {
    28. greetedReplyTo.whenComplete(
    29. (greetedReplyToRef, exc2) -> {
    30. if (exc2 == null) {
    31. greeterRef.tell(new HelloWorld.Greet("Akka", greetedReplyToRef));
    32. }
    33. });
    34. });

    Actor 可以通过返回Behaviors.stopped作为下一个行为来停止自己。

    通过使用父 Actor 的ActorContextstop方法,在子 Actor 完成当前消息的处理后,可以强制停止子 Actor。只有子 Actor 才能这样被阻止。

    子 Actor 将作为父级关闭过程的一部分被停止。

    停止 Actor 产生的PostStop信号可用于清除资源。请注意,可以选择将处理此类PostStop信号的行为定义为Behaviors.stopped的参数。如果 Actor 在突然停止时能优雅地停止自己,则需要不同的操作。


    英文原文链接Actor lifecycle.