scalaakkaakka-typed

What is the type of an Akka (Typed) actor Behavior that handles no messages?


Suppose I am defining a Behavior for an Akka (Typed) actor that will perform a concurrent computation, report its result to the actor that spawned it, and then stop.

If I initialize this actor with all of the inputs to the computation, plus a reference to its "parent", then it will not ever need to receive an incoming message of any type.

I would create this Behavior with Behaviors.setup, passing it a function that performs the computation, and then returns Behaviors.stopped.

Akka (Typed) requires me to provide a result type of some Behavior[T] for the function that will return this Behavior. And while I could assign to T the type of the result message that the Behavior will send, that doesn't seem correct. Isn't T meant to constrain what messages an actor can receive? And therefore, if I define T in terms of the type of message that the actor will send, am I not "lying" to the compiler?

In fact, this Behavior cannot - and will not - handle any incoming messages whatsoever.

Is there a more correct type that I can assign to this Behavior?

Or am I somehow missing the point of typed actor behaviors?

Example:

In the code below, my apply returns Behavior[ Result ], but this is a lie. It won't ever receive or handle a Result message. (It will only send one.)

import akka.actor.typed.{ ActorRef, Behavior }
import akka.actor.typed.scaladsl.Behaviors

object ConcurrentComputation {

  sealed trait Result
  final case class Success( result : Double ) extends Result
  final case class Failure( exception : Throwable ) extends Result

  def apply(
    argX : Double,
    argY : Double,
    parent : ActorRef[ Result ]
  ) : Behavior[ Result ] = Behaviors.setup(
    context => {
      try {
        Success( compute( argX, argY ) )
      }
      catch {
        case e : Throwable => Failure( e )
      }

      Behaviors.stopped
    } 
  )

  // Never mind what's actually being done.
  def compute( x : Double, y : Double ) : Double = ???
}


Solution

  • In general it is used Behaviors.setup[Nothing] for behaviors that don´t receive any message. It is supposed that an actor receives messages, but sometimes they don´t. For example, when you create an ActorSystem in Akka Typed you need to provide a Behavior for the user guardian actor, this actor is not going to receive any message, and you create the behavior for that actor as Behavior[Nothing].

    This type represents that this actor can not receive any message because "there exist no instances of this type" (Nothing type).