The receive
method defines an actor's behavior in Akka actors. I am looking for an approach that can give me all the different messages (and their types) an actor can process preferably at runtime in Scala.

- 845
- 6
- 26
-
4That is not possible. You might want to look at akka-typed if you need such guarantees. – rethab Nov 20 '18 at 20:37
-
1Akka typed cannot give the "types" of the messages that are able to be handled. Scala is not a dependently typed language, so types are not first-class. Akka typed _can_ enforce that only certain messages are able to be handled by a certain "actor", though. – erip Nov 20 '18 at 20:38
-
Just to be clear, you mean to say there is no reflective way to access an actor, its receive method and then list all the cases it handles? – Gakuo Nov 20 '18 at 20:46
-
2No, there is not. The `receive` method is passed a `PartialFunction[Any, Unit]`. In akka typed, you necessarily specify the type of messages that can be handled. – erip Nov 20 '18 at 20:54
-
1Note also that through the use of `context.become`, an actor can dynamically change its behavior (the `receive` method is just the default if the actor hasn't `context.become`d). – Levi Ramsey Nov 21 '18 at 03:08
-
1The behavior of a running actor is stored as a private field (`behaviorStack` in the `ActorCell`). If you could get access to that field, you could take its headto get the current behavior, which is a `PartialFunction[Any, Unit]`. From that, you can pass messages to the `isDefinedAt` method. The most that this will do is let you have a list of messages that the actor could process at that moment in time, which isn't quite what you're looking for, but that's OK because barring a major JVM exploit, you're not going to get access to that private field. – Levi Ramsey Nov 21 '18 at 03:15
-
The foregoing is based on the current HEAD on github. `ActorCell` is an internal API and highly subject to change. – Levi Ramsey Nov 21 '18 at 03:16
-
@LeviRamsey, You seem to be saying that for one to get the messages processed by the actor, one would have to send a series of messages and see if each is processed by the "receive" of the actor. It appears the best approach to this might be the static analysis of the actor. – Gakuo Nov 21 '18 at 10:31
-
It's not possible to get state of an actor. – Raman Mishra Nov 21 '18 at 13:18
1 Answers
Direct Answer
Unfortunately the functionality that you are asking for is not available with akka
. The receive
method is defined as:
type Receive = PartialFunction[Any, Unit]
abstract def receive : Actor.Receive
There is no way for a PartialFunction
to enumerate all types that it can process. Further, once an Actor
has been instantiated into an ActorRef
you don't have access to the underlying receive
method.
One alternative is to define your receive outside of the Actor
implementation and then use the isDefinedAt
method of PartialFunction
to test a particular value:
object MyActor {
val myPartial : Receive = {
//receive functionality
}
}
class MyActor extends Actor {
override def receive : Receive = MyActor.myPartial
}
//test if a value can be processed by MyActor
val testValue = 42
val testValueIsDefined = MyActor.myPartial.isDefinedAt(testValue)
Indirect Answer
If you organize your code correctly then the foundation of your question becomes unnecessary.
I've found a good practice is to strictly declare what types of inputs an Actor can receive:
sealed trait MyActorInputs
case class Foo(value : Int) extends MyActorInputs
case class Bar(value : String) extends MyActorInputs
object MyActor {
val processInput : MyActorInput => Unit = ???
}
class MyActor extends Actor {
override def receive : Receive = {
case input : MyActorInput =>
MyActor.processInput(input)
case unknown =>
System.error.println(s"MyActor received unknown input: $unknown")
}
}
This technique does not provide compiler time checks or strict guarantees, but if you adopt it across all of your Actors then it tends to make life easier for bigger projects. It would also allow you to use reflection to dynamically get a list of available input types.

- 17,373
- 7
- 77
- 125
-
Your answer confirms that it is indeed impossible to reflect on the types of a partial function (receive). You further give insights on how I would write an actor program that I can reflect on. This is handy information. However, I intend to amplify Akka Scala tests.These will be actors programmed by other developers. The developer will also write manual tests which I seek to amplify automatically. To amplify manually written tests, I will need to access the types of messages processed by the actors. You have shown that it is not dynamcally possible. So I turn to static analysis – Gakuo Nov 21 '18 at 14:00
-
1Note also that just because a `PartialFunction[X, Y]` does not guarantee handling any `X` it's given. – Levi Ramsey Nov 26 '18 at 18:16