This is a design question;
Say I have a tree of actors which do a bunch of processing. The processing is kicked off by a client/connection actor (i.e. the tree is the server). Eventually the client actor wants a response. I.e. I have an actor system that looks like this.
ActorA <---reqData--- Client_Actor
| msgA /|\
\|/ |
ActorB |
msgB | \ msgD |
\|/ \/ |
ActorC ActorD---------msgY-->|
|_____________msgX_________|
The response that the client system wants is the output from the leaf actors (i.e. ActorC
and/or ActorD
). These actors in the tree may be interacting with external systems. This tree may be a set of pre-defined possibly routed actors (i.e. so Client_actor
just has a actorref to the root of the actor tree, ActorA
).
The question is what is the best pattern to manage sending the response (msgX
&/or msgY
) from the final/leaf actors back to the client actor?
I can think of the following options;
msgX
or msgY
, send it back to the original sender ref so the messages are passed back up through the tree. I.e each actor will keep a ref of the original sender. Client_Actor
ref in the reqData
message and replicate this for all messages used in the tree so the leaf actors can reply directly to the Client_actor
... This seems like the most performant option. Not sure how to do this (I'm thinking a trait somehow on the message case classes that holds the client actor ref)...FYI I'm using Akka 2.2.1.
Cheers!
You could use the forward
method to forward the message from the original sender to the child sender at each level.
in Client_Actor:
actorA ! "hello"
in ActorA:
def receive = {
case msg =>
???
actorB forward msg
}
in ActorB:
def receive = {
case msg =>
???
actorC forward msg
}
in ActorC:
def receive = {
case msg =>
???
sender ! "reply" // sender is Client_Actor!
}
In this case, the 'sender' field of the message will never change, so ActorC will reply to the original Client_Actor!
You can extend this further by using the tell
method variant that lets you specify the sender:
destinationActor.tell("my message", someSenderActor);