2
votes

I am using scala akka actor model. I have a parent actor create n child actors. Child actors first talk with each other and then report the answer to the master actor. But I could not make it work for the report part. The code structure is as follows:

class Master(n:Int) extends Actor{
    val system =ActorSystem("mysystem")
    for(i <- 1 to n){
        val child=system.actorOf(Props(new Node),name=i.toString) 
    }
    ... code let child actor talk with each other ...
    def receive={
        case _=>"received"
    }
}
class Node extends Actor{
    def receive={
        case => ... some code talking with each other...
                var master=context.actorSelection("../Master")
                master ! "talk back to master"
    } 
}
def main() {
    val Master=system.actorOf(Props(new Master(10)),name="Master")
}
3
This line: ` val child=system.actorOf(Props(new Node),name=i.toString) ` ought to be ` val child=context.actorOf(Props(new Node),name=i.toString)`Viktor Klang

3 Answers

3
votes

Have the Master pass its self-reference to the Nodes. The relevant changed lines are:

... // In Master:
val child=context.actorOf(Props(new Node(self)),name=i.toString)
...
... // Definition of Node:
class Node(master: ActorRef) extends Actor{
...
//var master=context.actorSelection("../Master") - this line no longer required.
... //etc.
1
votes

Is there any reason why do you create new ActorSystem? Usually it is created only once, but you already have an actor which means that you already have a system, no need to create it twice. The ActorSystem is extremely heavyweight, it allocates threads, read configuration of dispatchers, remote functionality, addresses, etc. You should never create a new one, unless you have very good reason to do that.

I'd recommend to remove creation of ActorSystem, use context instead of system when creating child actors. With that you can use context.parent in your Node to get the Master, because it is supervisor of all your children.

Also the query ../Master selects a sibling rather than parent. You probably wanted .. which results in exactly the same as context.parent, but context.parent should be faster

0
votes

Try

val master = context.actorSelection("/user/Master")
master ! "talk back to master"

You also may want to take a look at this entry in the documentation.