Best way to deal with Actors that integrate other Actor Data?

32 views
Skip to first unread message

kraythe

unread,
Jun 22, 2016, 5:37:43 PM6/22/16
to Akka User List
Lets say I create an actor that will serve JSON to an end user but that actor returning the OverviewJson has to get data from three different actors and wait for them all to return a response before proceeding. Now I could create an actor that uses the ask patter to call all three other actors but that seems like it might be a bit heavyweight. I don't like using ask because of the concurrency involved. What I was wondering is if anyone had ideas for doing this without ask. However, at some point i have to return the data synchronously. After all the user is on the endpoint waiting for a response so I cant just message them asynchronously. 

One thought i had was to create a short term actor that send the messages to the other actors in the preStart and then waited until it collected all data with all three pieces collected and then returned to the user the created info. This seems to be exactly what the Ask pattern does and so I wonder if I am any better off then I would be just using Ask. 

Thanks for the feedback. 

Martynas Mickevičius

unread,
Jun 24, 2016, 1:17:25 AM6/24/16
to akka...@googlegroups.com
Hi,

in the short term actor situation that you described (these are sometimes also called per-request actors), you can send to the short term actor something, that lets you complete the original request that arrived to the endpoint. I do not know what you are using for handling requests, but akka-http has completeWith directive, which allows you to get a function, which can be used to complete the original request. You can send this function to your per-request actor and complete the request from there when all of the required data returns from the various actors. In this case you will be able to use tell when sending original request to the per-request actor.

--
>>>>>>>>>> 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 akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Justin du coeur

unread,
Jun 24, 2016, 8:56:58 AM6/24/16
to akka...@googlegroups.com
Keep in mind, ask() is pretty optimized -- it's creating pseudo-Actors under the hood, but as I understand it they're a bit lighter-weight than creating ordinary Actors.  So I wouldn't necessarily count on your own Actor being more efficient.  The per-request Actor may be the right way to go architecturally -- that actually wouldn't surprise me -- but it's not obvious which way would be fastest.


As for the concurrency issues involved with using ask inside an Actor, you *may* want to take a look at the Requester library, which adds request(), a higher-level variant of ask() that is specifically designed to work well for complex scenarios like you are describing.  Assuming the requests to the three other Actors are all independent, this comes out something like (in Scala):

def receive = {
  case Thingy(x) => {
    // Send the requests:
    val reqA = OtherActor1.request(Foo(x))
    val reqB = OtherActor2.request(Bar(x))
    val reqC = OtherActor3.request(Baz(x))
    // Then collect the responses:
    for {
      a <- reqA
      b <- reqB
      c <- reqC
    }
      // We have all the responses, so send the collated response back to the original sender:
      sender ! MyResponse(a, b, c)
  }
}

All the concurrency problems are handled under the hood, by quietly looping the responses back into the receive function.

It *does* add a small amount of extra overhead, and I know you're sensitive to that (and perhaps more importantly, I don't think Requester has been tried from Java yet, so there may be API issues), but it might at least provide an illustration of how to deal with complex multi-Actor protocols like this.  (I deal with this sort of thing a *lot* in Querki, which is why I developed the library.)

--
Reply all
Reply to author
Forward
0 new messages