Actor ask pattern in Akka typed
Yes, in akka typed the ask pattern is used in slightly different way. But how ?
Actually, an akka ask pattern itself is an actor. Wherever you are creating it, you are creating an actor. Actor will have a behaviour. In typed akka the behaviour is also typed, that is the difference creator compared with the classic akka ask pattern. So, for the akka ask actor behaviour you need to arrange protocol type.
We will here create an ask pattern within an Actor.
object AmberHeard { sealed trait HerdCommand final case class WhatsUp(replyTo: ActorRef[JohnnyDepp.Asker]) extends HerdCommand def apply(): Behavior[HerdCommand] = Behaviors.receive { case (context, WhatsUp(replyTo)) => replyTo ! JohnnyDepp.Response("Don't do this . . . ") Behaviors.same } } object JohnnyDepp { sealed trait Command // protocol for JohnnyDepp actor case object Hi extends Command final case class ResponseAdapter(message: String) extends Command sealed trait Asker // protocol for ask actor final case class Response(msg: String) extends Asker def apply(): Behavior[Command] = Behaviors.setup { context => val heardRef = context.spawn(AmberHeard(), "beautifulHeard") Behaviors.receiveMessage { case Hi => implicit val timeout: Timeout = 1.seconds context.ask(heardRef, AmberHeard.WhatsUp.apply) { case Success(Response(msg)) => ResponseAdapter(msg) case Failure(_) => ResponseAdapter("What the fuck !") } Behaviors.same case ResponseAdapter(message) => println(message) Behaviors.same } } }
let me explain this part
context.ask(herdRef, AmberHeard.WhatsUp.apply) { case Success(Response(msg)) => ResponseAdapter(msg) case Failure(_) => ResponseAdapter("What the fuck !") }
Here, though it seems we are asking, it is not only we are just asking, we are also producing an Ask actor the behaviour of which is Behavior[Asker]. We are doing here another thing that is we are producing a actor ref of the actor we are going to ask-
val heardRef = context.spawn(AmberHeard(), "beautifulHeard")
In asking we are passing this above ref , so that the Asker actor send a message to heardRef , and in the message the Asker actor is also sending its own actor ref.
Everything is done. Now Asker actor is waiting for the response back. When it get back the response it collects the payload (message) from the Resopnse(message:String) and sends it to
JonneyDepp actor ref as -
final case class ResponseAdapter(message: String) extends Command
And that is how it works....... Yes, like classic one we can not send ask request to any Random Actor. BECAUSE BECAUSE--
final case class WhatsUp(replyTo: ActorRef[JohnnyDepp.Asker]) extends HerdCommand
that actor needs to have protocol that accepts the asking actor's actorRef.
Out of actor body we can also use ask pattern. that is very similar to it, instead of sending the response to another actor as adapted message it produces a Future of Protocol .
implicit val timeout: Timeout = 3.second implicit val executionContext: ExecutionContext = actorSystem.executionContext (heardRef ? (ref => AmberHeard.WhatsUp(ref))).map{ Response(msg) => println(msg) }
That is very easy !!!!!