passing around an ActorRef is safe, because an ActorRef is an immutable
structure: http://doc.akka.io/api/akka/2.4.1/akka/actor/ActorRef.html
there is an alternative however, which i think is less 'leaky'. in the
handling of Request in actor A, you can use ask() and pipeTo():
def receive = {
case req: Request if some_special_condition =>
actor2.ask(new HandleSpecialCondition()).pipeTo(sender())
case req: Request =>
sender() ! new NormalResponse()
}
a couple things to note: 1) i broke up your receive function into two
cases using a guard just for clarity, 2) i made up NormalResponse, and
3) ask() and ? are interchangeable, i prefer ask(). hopefully the
intent is clear.
what i like about this pattern is that actor B doesn't need to know
anything about the the requesting actor. you also get timeout support
by passing a timeout to the ask() or putting an implicit timeout in
scope, which is useful if actor B is doing something like querying a
database or something else which can fail. the disadvantage to this
approach is that ask() creates an intermediate actor 'behind the
scenes', so there is (small) overhead in terms of allocation and
scheduling. this overhead is something you probably shouldn't worry
about, but it's good to understand what's happening underneath.
-Michael
On 01/20/16 00:17, Karthik Deivasigamani wrote:
Hi,
I have a use case where I have to pass message between actors and
send a response back to the caller.
Once I get a request I invoke Actor A, which will do some DB call and
return results. But in certain cases actor A has to invoke actor B and
get some results from Actor B. It then has to return that result back
to the guy who sent the request. I accomplished this by passing a
reference to the original sender in the message that I send to actor B
as shown below :
|
App{
val actor1 =system.actorOf(A)
val actor2 =system.actorOf(B)
//I want actor 1 to process this request
actor1 ?newRequest("process this")
}
caseclassHandleSpecialConition(sender :ActorRef)
caseclassSpecialConditionResponse(sender :ActorRef,response:String)
A extendsActor{
defreceive ={
casereq : Request=>{
//Checks for special condition and if so sends a message to actor2
and the message is embedded with a reference to the sender to whom we
have to respond back
if(some_special_condition){
actor2 !newHandleSpecialCondition(sender)
}else{
"sending_back_response"
}
}
//when we get the response from Actor B it will contain the
reference to the original sender and we reply back to him
case response : ||SpecialConditionResponse|| => {
response.sender ! response.response
}
}
}
B extendsActor{
defreceive ={
casem :HandleSpecialCondition{
//reply back to actor 1
sender !new|SpecialConditionResponse|(m.sender, "Response for
special condition")
}
}
}
|
I wanted to ask if there is better way to accomplish this without
passing the original sender's reference around. Is there something
wrong with this kind of approach.
Thanks,
Karthik
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ:
http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google
Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
--
Read the docs: http://akka.io/docs/
Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.