We have some code that receives into its behaviour and uses orElse so that another behaviour’s signal handler can continue handling signals i.e.:
Behaviors
.receive[T] {...}
.orElse(behavior) // handle signals immediately
What we’re seeing is that the signal handling of behavior isn’t called. The specific signal in use here is Terminated.
The API doc for orElse states:
Composes this
Behavior with a fallbackBehaviorwhich is used when thisBehavior` doesn’t handle the message or signal…
However, I think that in the case of the Terminated signal, this isn’t the case. Looking at the code of Behavior, I see the following:
def interpretSignal[T](behavior: Behavior[T], ctx: TypedActorContext[T], signal: Signal): Behavior[T] = {
val result = interpret(behavior, ctx, signal)
// we need to throw here to allow supervision of deathpact exception
signal match {
case Terminated(ref) if result == UnhandledBehavior ⇒ throw DeathPactException(ref)
case _ ⇒ result
}
}
This appears to handle the termination signal especially, as the comment states. However, it also appears that the orElse behavior doesn’t get the opportunity to execute.
I was hoping that the correct API behaviour could be clarified.
Relevant code example: MQTT streaming: SourceQueue backpressure by longshorej · Pull Request #1577 · akka/alpakka · GitHub
Naturally, I’m happy to raise an issue if there is one. Thanks for your guidance.