Scala Akka actors - getting the state of an actor
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.
scala akka actor
|
show 4 more comments
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.
scala akka actor
4
That is not possible. You might want to look at akka-typed if you need such guarantees.
– rethab
Nov 20 '18 at 20:37
1
Akka 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
2
No, there is not. Thereceive
method is passed aPartialFunction[Any, Unit]
. In akka typed, you necessarily specify the type of messages that can be handled.
– erip
Nov 20 '18 at 20:54
1
Note also that through the use ofcontext.become
, an actor can dynamically change its behavior (thereceive
method is just the default if the actor hasn'tcontext.become
d).
– Levi Ramsey
Nov 21 '18 at 3:08
1
The behavior of a running actor is stored as a private field (behaviorStack
in theActorCell
). If you could get access to that field, you could take its headto get the current behavior, which is aPartialFunction[Any, Unit]
. From that, you can pass messages to theisDefinedAt
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 3:15
|
show 4 more comments
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.
scala akka actor
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.
scala akka actor
scala akka actor
asked Nov 20 '18 at 20:33
GakuoGakuo
375212
375212
4
That is not possible. You might want to look at akka-typed if you need such guarantees.
– rethab
Nov 20 '18 at 20:37
1
Akka 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
2
No, there is not. Thereceive
method is passed aPartialFunction[Any, Unit]
. In akka typed, you necessarily specify the type of messages that can be handled.
– erip
Nov 20 '18 at 20:54
1
Note also that through the use ofcontext.become
, an actor can dynamically change its behavior (thereceive
method is just the default if the actor hasn'tcontext.become
d).
– Levi Ramsey
Nov 21 '18 at 3:08
1
The behavior of a running actor is stored as a private field (behaviorStack
in theActorCell
). If you could get access to that field, you could take its headto get the current behavior, which is aPartialFunction[Any, Unit]
. From that, you can pass messages to theisDefinedAt
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 3:15
|
show 4 more comments
4
That is not possible. You might want to look at akka-typed if you need such guarantees.
– rethab
Nov 20 '18 at 20:37
1
Akka 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
2
No, there is not. Thereceive
method is passed aPartialFunction[Any, Unit]
. In akka typed, you necessarily specify the type of messages that can be handled.
– erip
Nov 20 '18 at 20:54
1
Note also that through the use ofcontext.become
, an actor can dynamically change its behavior (thereceive
method is just the default if the actor hasn'tcontext.become
d).
– Levi Ramsey
Nov 21 '18 at 3:08
1
The behavior of a running actor is stored as a private field (behaviorStack
in theActorCell
). If you could get access to that field, you could take its headto get the current behavior, which is aPartialFunction[Any, Unit]
. From that, you can pass messages to theisDefinedAt
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 3:15
4
4
That is not possible. You might want to look at akka-typed if you need such guarantees.
– rethab
Nov 20 '18 at 20:37
That is not possible. You might want to look at akka-typed if you need such guarantees.
– rethab
Nov 20 '18 at 20:37
1
1
Akka 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
Akka 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
2
2
No, 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
No, 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
1
1
Note 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 3:08
Note 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 3:08
1
1
The 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 3:15
The 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 3:15
|
show 4 more comments
1 Answer
1
active
oldest
votes
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.
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
1
Note also that just because aPartialFunction[X, Y]
does not guarantee handling anyX
it's given.
– Levi Ramsey
Nov 26 '18 at 18:16
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401081%2fscala-akka-actors-getting-the-state-of-an-actor%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
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
1
Note also that just because aPartialFunction[X, Y]
does not guarantee handling anyX
it's given.
– Levi Ramsey
Nov 26 '18 at 18:16
add a comment |
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.
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
1
Note also that just because aPartialFunction[X, Y]
does not guarantee handling anyX
it's given.
– Levi Ramsey
Nov 26 '18 at 18:16
add a comment |
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.
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.
edited Nov 21 '18 at 13:20
answered Nov 21 '18 at 13:04
Ramon J Romero y VigilRamon J Romero y Vigil
12k24272
12k24272
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
1
Note also that just because aPartialFunction[X, Y]
does not guarantee handling anyX
it's given.
– Levi Ramsey
Nov 26 '18 at 18:16
add a comment |
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
1
Note also that just because aPartialFunction[X, Y]
does not guarantee handling anyX
it's given.
– Levi Ramsey
Nov 26 '18 at 18:16
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
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
1
1
Note 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
Note 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
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401081%2fscala-akka-actors-getting-the-state-of-an-actor%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
That is not possible. You might want to look at akka-typed if you need such guarantees.
– rethab
Nov 20 '18 at 20:37
1
Akka 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
2
No, there is not. The
receive
method is passed aPartialFunction[Any, Unit]
. In akka typed, you necessarily specify the type of messages that can be handled.– erip
Nov 20 '18 at 20:54
1
Note also that through the use of
context.become
, an actor can dynamically change its behavior (thereceive
method is just the default if the actor hasn'tcontext.become
d).– Levi Ramsey
Nov 21 '18 at 3:08
1
The behavior of a running actor is stored as a private field (
behaviorStack
in theActorCell
). If you could get access to that field, you could take its headto get the current behavior, which is aPartialFunction[Any, Unit]
. From that, you can pass messages to theisDefinedAt
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 3:15