如何使用 Behavior.receiveMessage 处理生命周期信号

zer*_*ing 2 scala akka akka-typed

我有一个演员,创建如下:

    Behaviors.setup { context =>
          val greeter = context.spawn(HelloWorld.greeter, "greeter")

          Behaviors.receiveMessage { message =>
            val replyTo = context.spawn(HelloWorldBot.bot(greetingCounter = 0, max = 3), message.name)
            greeter ! HelloWorld.Greet(message.name, replyTo)
            Behaviors.same
          }
        }
Run Code Online (Sandbox Code Playgroud)

我想在文档中处理信号消息(例如 PostStop)Behaviors.receiveMessage说:

接收的简化版本,只有一个参数 - 要处理的消息。当上下文已经可以通过其他方式访问时很有用,比如被包装在一个设置或类似的东西中。构建可以对传入消息和生命周期信号做出反应的参与者行为。从另一个actor(或作为akka.actor.typed.ActorSystem的守护者)生成这个actor后,它将在允许访问系统、生成和观看其他actor等的ActorContext中执行。与使用AbstractBehavior相比,这个工厂是一种更实用的定义行为的风格。处理下一条消息会产生可能与此不同的新行为。通过返回保持新的不可变状态的新行为来维护状态。

但是如何在Behaviors.receiveMessage.

这是文档的链接https://doc.akka.io/api/akka/current/akka/actor/typed/scaladsl/Behaviors $.html#receiveMessageT:akka.actor.typed.scaladsl.Behaviors.Receive[ ]

Arn*_*sen 5

因为receiveMessage[A]只能匹配符合类型的消息,A并且您无法声明A包含系统消息PostStop的类型等。相反,Akka-Typed 有一个专用的receiveSignal.

鉴于您的示例,您已经通过 捕获共享上下文Behavior.setup,您可以链接receiveSignal到消息行为以成为相同行为的一部分:

Behaviors.setup { context =>
      val greeter = context.spawn(HelloWorld.greeter, "greeter")

      Behaviors.receiveMessage { message =>
        val replyTo = context.spawn(HelloWorldBot.bot(greetingCounter = 0, max = 3), message.name)
        greeter ! HelloWorld.Greet(message.name, replyTo)
        Behaviors.same
      }.receiveSignal {
         case (context, PostStop) =>
           context.log.info("behavior stopped")
           Behaviors.same
    }
Run Code Online (Sandbox Code Playgroud)