Decoy
Decoy

Reputation: 317

Akka: Creating many child actors vs. reusing a single child actor

I'm quite new to Akka and I have a (hopefully) simple question. I have an actor that needs to repeatedly do a certain small subtask - that is, each time this actor receives a message, it will have to do N subtasks. This subtask is something that I've designated to a child actor. My question is, should I be creating a new instance of a child actor for each of these subtasks? Or should I simply spawn a single child actor, and send it N messages? What's the best practice in such a situation?

To better illustrate my question, here are two dumbed-down examples (In Java - but hopefully simple enough for you Scala guys!):

This first actor class creates a single child actor upon construction, and then sends many messages to that single child actor.

public class ParentActor extends UntypedActor {

    private final ActorRef childActor;

    public ParentActor() {
        this.childActor = getContext().actorOf(Props.create(childActor.class));
    }

    @Override
    public void onReceive(Object msg) {
        for (int i=0; i<1000; i++) {
            this.childActor.tell("Some message", getSelf());
        }
    }
}

Now, compare it to the following actor, which spawns a new child actor for each message that needs to be sent.

public class ParentActor extends UntypedActor {

    @Override
    public void onReceive(Object msg) {
        for (int i=0; i<1000; i++) {
            final ActorRef childActor = getContext().actorOf(Props.create(childActor.class));
            childActor.tell("Some message", getSelf());
        }
    }
}

Thanks!

Upvotes: 6

Views: 2948

Answers (1)

cybye
cybye

Reputation: 1171

Distributing work to actors can be done in akka using Routers.

The idea is to move the selection of the child rsp worker actor into the message-flow.

See the top example in the referenced doc. The master creates a set of child-actors, called routees and adds them to a router:

router = new Router(new RoundRobinRoutingLogic(), routees);

the router can be configured to use a set of different routing-logic implementations, here a simple round-robin logic.

When a message is sent to one of the child actors, you can just sent it to the router and it cares for selecting the right child and sending it there:

router.route(msg, getSender());

The getSender can be used to pass the message sender in case the message is orginally received in the worker, or you just pass the result of 'getSelf()' (or maybe just nothing, unsure) to send it directly.

Upvotes: 5

Related Questions