1
votes

I'm using akka actors to achieve parallel processing of some http requests. I've initailized a pool of actors using RoundRobinPool like:

ActorRef myActorPool = actorSystem.actorOf(new RoundRobinPool(200).props(Props.create(MyActor.class, args)), MyActor.class.getSimpleName());

It is working fine. But after the process is running for sometime, i'm getting following error

java.util.concurrent.CompletionException: akka.pattern.AskTimeoutException: Recipient[Actor[akka://web_server/user/MyActor#-769383443]] had already been terminated. Sender[null] sent the message of type "com.data.model.Request".

So I've overridden postStop method added a log statement there.

@Override
public void postStop() {
    log.warn("Actor is stopped");
}

Now, I can see in the logs that the actors are getting stopped. But I'm not sure for which request it is happening. Once all the actors in the pool terminates (200 is the pool size I've set), I'm getting AskTimeoutException as said before. Is there anyway to debug why the actors are getting terminated?

EDIT 1

In the controller, I'm using the created actor pool like

CompletableFuture<Object> s = ask(myActorPool, request, 1000000000).toCompletableFuture();
return s.join();

The actor processes one kind of messages only.

@Override
public AbstractActor.Receive createReceive() {
    return receiveBuilder()
            .match(Request.class, this::process)
            .build();
}

private void process(Request request) {
    try {
        // code here
    } catch (Exception e) {
        log.error(e.getMessage(), e);
        getSender().tell(new akka.actor.Status.Failure(e), getSelf());
    }
}
1
if you can add the code snipt that would be helpful.Raman Mishra
This is how are you creating the actors. How are you actually using the actors?curious
Looking at the code looks like you are only sending response to the sender only when there is an exception (in the catch block). You need to send the response in try block as well.curious
I haven't added the code in try block but it actually sends response to sender.pkgajulapalli
I don't know if it is related with this issue but you are blocking threads on s.join(). Depending on your project settings/framework you could run out of available threads so the entire app could be sluggish so the timeouts.RoberMP

1 Answers

-2
votes

As far as you have described the probelm it seems you are processing your data inside the ask call and taking more time than askTimeout, and you are getting the error.

What you can do is either increase the askTimeout or do less processing inside tha ask call.

you should not do CPU bound operations inside the ask call, it can cause slowing down your system it is recommended that you should do the I/O bound operations inside the ask call. That way you can leverage the actors.

For example:

val x=x+1   // CPU bound operation should not do inside the ask call

some db call you can do inside the ask call that is preferable.