Akka Typed Behavior.orElse appears not to propagate termination signals


(Christopher Hunt) #1

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.:

        .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: https://github.com/akka/alpakka/pull/1577/files#diff-a2dfb01266e608741b917c05b6a7e07aR26

Naturally, I’m happy to raise an issue if there is one. Thanks for your guidance.

(Patrik Nordwall) #2

Good catch, I think that should be changed so the Terminated signal is passed on to all orElse. The DeathPactException might have to be solved elsewhere. Issue please.

(Christopher Hunt) #3

Thanks. Issue created: https://github.com/akka/akka/issues/26518