Reputation: 34071
I have an actor, that is created as follows:
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
}
}
I would like to handle Signals messages(for example PostStop) within the Behaviors.receiveMessage
and in the doc says:
Simplified version of Receive with only a single argument - the message to be handled. Useful for when the context is already accessible by other means, like being wrapped in an setup or similar. Construct an actor behavior that can react to both incoming messages and lifecycle signals. After spawning this actor from another actor (or as the guardian of an akka.actor.typed.ActorSystem) it will be executed within an ActorContext that allows access to the system, spawning and watching other actors, etc. Compared to using AbstractBehavior this factory is a more functional style of defining the Behavior. Processing the next message results in a new behavior that can potentially be different from this one. State is maintained by returning a new behavior that holds the new immutable state.
But how to implement the lifecycle Signals within the Behaviors.receiveMessage
?
Here is the link to the doc https://doc.akka.io/api/akka/current/akka/actor/typed/scaladsl/Behaviors$.html#receiveMessageT:akka.actor.typed.scaladsl.Behaviors.Receive[T]
Upvotes: 2
Views: 1111
Reputation: 14404
Because receiveMessage[A]
can only match on messages that conform to type A
and there is no way for you to declare a type A
that includes the system messages for PostStop
, etc. Instead Akka-Typed has a dedicated receiveSignal
.
Given your example, where you are already capturing a shared context via Behavior.setup
, you can chain receiveSignal
onto the message behavior to be part of the same behavior:
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
}
Upvotes: 5