JasonG
JasonG

Reputation: 5962

Akka2.1/Scala - Nodes created in actor do not show up in context.children?

I have an abstract class that is an actor and it has a method like this

def getNewConnection(id: String): ActorRef

A class that subclasses it defines the method.

  override def getNewConnection(id: String): ActorRef = {
    val actorRef = system.actorOf(Props(new RsvpClusterableClientConnection(service, id)))
    actorRef ! Subscribe(clientConnectionId)
    actorRef
  }

And then it stores that actorRef.

The thing is, when I go context.children it's empty. Similarly if the child actor goes context.parent ! "HEY!" the parent won't get the message. If I look at the path, the context.partent shows /users/ and the REAL parent actor is actually something like /users/$2b

I can't find anyone with similar issues. This is in a test that goes something like this:

class ZombieTest extends TestKit(ActorSystem("zombietest")) with HelperSpec with ShouldMatchers {

  import ExecutionContext.Implicits.global
[...]
val conActor = system.actorOf(Props(new ConnectionActor(testService1)))
}

EDIT

AgileSteel is correct. creating from system will create a top level actor. Creating from context will create a child.

From akka documentation:

Creating Actors with default constructor

object Main extends App {  
val system = ActorSystem("MySystem")   val myActor =
system.actorOf(Props[MyActor], name = "myactor") The call to actorOf

returns an instance of ActorRef. This is a handle to the Actor instance which you can use to interact with the Actor. The ActorRef is immutable and has a one to one relationship with the Actor it represents. The ActorRef is also serializable and network-aware. This means that you can serialize it, send it over the wire and use it on a remote host and it will still be representing the same Actor on the original node, across the network.

In the above example the actor was created from the system. It is also possible to create actors from other actors with the actor context. The difference is how the supervisor hierarchy is arranged. When using the context the current actor will be supervisor of the created child actor. When using the system it will be a top level actor, that is supervised by the system (internal guardian actor).

class FirstActor extends Actor {   val myActor =
context.actorOf(Props[MyActor], name = "myactor")

Upvotes: 1

Views: 197

Answers (1)

agilesteel
agilesteel

Reputation: 16859

You should/must call actorOf on context instead of system when creating children.

Upvotes: 7

Related Questions