Scala Akka actors - getting the state of an actor












3















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.










share|improve this question


















  • 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 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





    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.becomed).

    – Levi Ramsey
    Nov 21 '18 at 3:08






  • 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
















3















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.










share|improve this question


















  • 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 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





    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.becomed).

    – Levi Ramsey
    Nov 21 '18 at 3:08






  • 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














3












3








3


1






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.










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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





    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.becomed).

    – Levi Ramsey
    Nov 21 '18 at 3:08






  • 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














  • 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 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





    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.becomed).

    – Levi Ramsey
    Nov 21 '18 at 3:08






  • 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








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.becomed).

– 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.becomed).

– 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












1 Answer
1






active

oldest

votes


















0














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.






share|improve this answer


























  • 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 a PartialFunction[X, Y] does not guarantee handling any X it's given.

    – Levi Ramsey
    Nov 26 '18 at 18:16











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
});


}
});














draft saved

draft discarded


















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









0














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.






share|improve this answer


























  • 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 a PartialFunction[X, Y] does not guarantee handling any X it's given.

    – Levi Ramsey
    Nov 26 '18 at 18:16
















0














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.






share|improve this answer


























  • 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 a PartialFunction[X, Y] does not guarantee handling any X it's given.

    – Levi Ramsey
    Nov 26 '18 at 18:16














0












0








0







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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 a PartialFunction[X, Y] does not guarantee handling any X 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








  • 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

















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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?