Как обработать сигнал жизненного цикла с Behavior.receiveMessage - PullRequest
1 голос
/ 01 июля 2019

У меня есть актер, который создается следующим образом:

    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
          }
        }

Я хотел бы обработать Сигналы сообщений (например, PostStop) в пределах Behaviors.receiveMessage и в документеговорит:

Упрощенная версия Receive только с одним аргументом - сообщение, которое будет обработано.Полезно, когда контекст уже доступен с помощью других средств, таких как завернутый в настройке или подобный.Создайте поведение актера, которое может реагировать как на входящие сообщения, так и на сигналы жизненного цикла.После порождения этого актера от другого актера (или в качестве хранителя akka.actor.typed.ActorSystem) он будет выполнен в ActorContext, который обеспечивает доступ к системе, порождает и наблюдает за другими акторами и т. Д. По сравнению с использованием AbstractBehavior этой фабрикиэто более функциональный стиль определения поведения.Обработка следующего сообщения приводит к новому поведению, которое потенциально может отличаться от этого.Состояние поддерживается путем возврата нового поведения, которое содержит новое неизменное состояние.

Но как реализовать сигналы жизненного цикла в Behaviors.receiveMessage?

Вот ссылка на документ https://doc.akka.io/api/akka/current/akka/actor/typed/scaladsl/Behaviors$.html#receiveMessageT:akka.actor.typed.scaladsl.Behaviors.Receive[T]

1 Ответ

2 голосов
/ 07 июля 2019

Поскольку 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
    }
...