I am confused about how I should resolve this scenario in a non-blocking manner.
Consider two actors Actor1
and Actor2
Within Actor1
Map<Int, Int> foo() {
List<String> finalList = foo_2();
Map<Int, Int> finalMap = // do stuff with finalList to get Map<Int, Int>;
return finalMap;
}
List<String> foo_2() {
CompletableFuture<List<String>> Querylist = ask(Actor2)
Querylist.get();
return QueryList;
}
Currently within foo_2, Querylist.get()
is a blocking call. I want to somehow resolve this in a non-blocking manner. I created a message adapter for Actor2
inside Actor1
so any messages that Actor2
sends will be handled by Actor1
.
I used the following approach to modify the blocking call
Map<Int, Int> foo() {
CompletionStage<List<String>> finalList = foo_2();
finalList.whenComplete(
// what to do here?
)
// Map<Int, Int> finalMap = // do stuff with finalList to get Map<Int, Int>;
return finalMap;
}
CompletionStage<List<String>> foo_2() {
CompletionStage<List<String>> Querylist = ask(Actor2)
return QueryList;
}
I am not sure how to correctly use the CompletionStage construct to get the same result I was getting with a blocking futures.get() call.
If you're using Akka Typed (implied from the tag), you shouldn't need a future or a message adapter at all. Just use ActorContext.ask
.
See the documentation for request-response with ask between two actors.
Broadly, you'd get rid of the foo
and foo_2
methods, move the message adapter you've set up into the ActorContext.ask
call, and replace the instances where you've previously called foo
with a call to ActorContext.ask
. If the reply your actor sends to the message which led to the ask depends on the response to the ask, then a good practice is to embed the required portions of state into the message the adapter generates.