Interesting ideas. Actor per request is something i didn't know about. I 
will research that. That would of course prevent a deadlock because the 
pool of actors would not be fixed. The question then becomes, in the domain 
management model I have (basically the actors are managing and extracting 
info from the domain model) id there a reason to NOT do an actor per 
request? Also I have to add one complication to the issue. Basically that 
the Actor has to run on the node that the data is resident on. Hazelcast 
splits up the data among the nodes and serializing the data (especially for 
large volumes) is an unscalable solution. I wrote a PartitionAwareRouter 
that sends the message to the node that holds that part of the map. This 
has to go to a fixed actor (specifically the actor for the router) on 
another node. I suppose one solution would be to have a variable size pool 
that can expand should there be need to do so. I wouldnt know how to go 
about that though. Essentially the pool would have a collection of x actors 
pre-started and only send a message to an actor if it is not processing a 
message and then expand the size of the actor pool if all actors are busy 
with a temporary actor. I wonder if I would be better off writing that as 
an actor with routing characteristics rather than a router. Mainly because 
I don't think I have a lot of control over the pool in a router. 

Any thoughts on that idea ? 

Thanks man. 

-- RObert

On Wednesday, August 26, 2015 at 3:10:31 PM UTC-5, Adam wrote:
>
> Ah... there it is - I missed that little Await there...
> Sorry :-)
>
>
> Anyway, I'd rewrite it differently.
> In my eyes you have a few options.
>
> If in order to fulfill a request, you don't need to maintain any state (in 
> your program, not in a DB, or something like Hazelcast), and the request is 
> local, then you can just use a future to begin with.
>
> Otherwise, use an actor.
> Even if you do need to maintain state, the question is for how long.
> In most cases, at least for parts of the request handling, you can extract 
> logic that only maintains state for the duration of the request.
> In such cases an actor per request pattern is very useful (we use it a 
> lot) and what you'll discover is that you often end up with a small (and 
> very simple) FSM.
>
> In your example it's possible to use this pattern:
>
> Actor A receives a request, for order history. It gets a customer from 
> cache and then starts an "actor per request" (Actor B) for the purpose of 
> accumalating all of the customer's orders.
> Actor B creates as many actor per request of type C and accumulates their 
> responses.
> Each Actor C gets 1 order from cache according to the id it got and asks 
> for the name of the customer of that order from Actor A (which isn't 
> blocked).
>
> Once Actor B is finished it can either reply back to the original 
> requester, or reply to A which will route the reply to the requester - it's 
> up to your messages protocol.
>
> And if that seems too complex, then you're correct.
> In the case above, there isn't really any state for any of the above 
> actors, so it's also possible to utilize the new Akka streams and write the 
> above logic much more succinctly (and probably with less bugs...). So this 
> is very similar to using futures, only it's implemented with actors.
>
> There are probably also other "prettier" options.
> The point is, though, that it's entirely possible to implement an 
> asynchronous chain of events that can never deadlock.
>
>
> On Wed, Aug 26, 2015 at 10:40 PM, kraythe <[email protected] <javascript:>> 
> wrote:
>
>> Hmm I don't know why you would think there is a race condition. The code 
>> calls an Await() on all the futures from the ASK to Order. Furthermore, the 
>> method NEEDS the result to the call to Order to finish the JSON map. How 
>> would you do this without a list of futures? Remember all of the data from 
>> the Order needs to be in the map before its returned. 
>>
>>
>> On Wednesday, August 26, 2015 at 1:53:19 PM UTC-5, Adam wrote:
>>>
>>> Compiler or not, the code above has a race condition and I'd bet that it 
>>> would return an empty map in most cases. The actor is sending the reply 
>>> without waiting fir the future to end. (It should not deadlock BTW). If 
>>> anything, I'd pipe the result to the sender.
>>>
>>> But a future is not needed at all in this case. Once an actor exits the 
>>> receive method it's free to process the next messages in it's mailbox. As 
>>> you haven't written any code that waits, a deadlock is impossible. That 
>>> said, it is possible to create a deadlock in akka (or any other 
>>> multithreaded framework). It's just harder, because everything is more 
>>> explicit and "waiting" is not even one if the primitives supported by 
>>> actors - you have to implement them.
>>>
>>> For this use case you need to define a protocol of messages between the 
>>> two actors (if they can be remote I'd include handling of dropped 
>>> messages). Such a protocol can distinguish between the initial request to 
>>> the customer actor and subsequent requests if that turns out to be needed.
>>>
>>> BTW, you should always send immutable data between actors and there's no 
>>> need for the default case where you call unhandled, if your using the Scala 
>>> API.
>>> On Aug 26, 2015 9:35 PM, "kraythe" <[email protected]> wrote:
>>>
>>>> Either way I have to return just the map to the sender that called with 
>>>> OrderHistory. In fact the sender could be on another node in the cluster 
>>>> so 
>>>> sending the futures is not a viable solution. This is a multiple node 
>>>> environment where the actors MUST run local to where Hazelcast stores the 
>>>> object to avoid heavy serialization overhead. In fact each of the orders 
>>>> themselves might be on another node. 
>>>>
>>>> However the principle question remains, "Will what I posted deadlock?"
>>>>
>>>> -- Robert
>>>>
>>>> On Wednesday, August 26, 2015 at 1:27:38 PM UTC-5, rrodseth wrote:
>>>>>
>>>>> Have you looked at Future.sequence? It turns a List[Future[A]] into a 
>>>>> Future[List[A]].
>>>>>
>>>>> Then you can pipe that result to the same actor or another, or add a 
>>>>> complete handler as you have done.
>>>>>
>>>>> On Wed, Aug 26, 2015 at 11:17 AM, kraythe <[email protected]> wrote:
>>>>>
>>>>>> I am using play framework with a mix of scala and java. I can return 
>>>>>> a promise to the play framework and that promise can call the actor to 
>>>>>> get 
>>>>>> the information in a future. No Problem there. The problem is when an 
>>>>>> actor 
>>>>>> (A) needs something from another actor (B) and B needs something from A. 
>>>>>> A 
>>>>>> sends to a list of Bs and B sends a different message to A and then 
>>>>>> composes it. Think of generating JSON from a Customer -> Order Situation 
>>>>>> where Orders can have several different customers. The order JSON needs 
>>>>>> to 
>>>>>> have info from the customer in detail but for each of the orders we have 
>>>>>> to 
>>>>>> return all customer ids involved in the order. At some point I need to 
>>>>>> collect the results from all the calls to B and shove them into the 
>>>>>> result 
>>>>>> map. I can pass the map in the message to B and have it add the data but 
>>>>>> then if I have a pool of 5 actors and 5 customers are processing then 
>>>>>> when 
>>>>>> it calls back into A to get the customer ids of other customers involved 
>>>>>> in 
>>>>>> the order, it needs to use an instance of actor A in the pool to 
>>>>>> accomplish 
>>>>>> this. If they are waiting on the completion of a future then that cant 
>>>>>> happen. 
>>>>>>
>>>>>> An example of what I am talking about is below. Please excuse that I 
>>>>>> coded this cold without compiling but hopefully you get the idea. 
>>>>>>
>>>>>> class CustomerActor extends Actor {
>>>>>>     override def receive: Receive = {
>>>>>>       case msg: OrderHistoryJsonMsg =>
>>>>>>         val customer = Customer.findInCacheById(msg.customerId)
>>>>>>         val jsonMap = scala.collection.mutable.Map()
>>>>>>         // init JSON with customer data.
>>>>>>         val selection = Akka.system().actorSelection("/user/orderActors")
>>>>>>         val futures = customer.orderIds.map(orderId => {
>>>>>>           val future = selection ? new OrderJsonMsg(orderId)
>>>>>>           future.onComplete(r => {
>>>>>>             // add data to JSON.
>>>>>>           })
>>>>>>           future
>>>>>>         })
>>>>>>         futures.foreach(f => Await.result(f, 1 seconds))
>>>>>>         sender ! jsonMap
>>>>>>       case msg =>
>>>>>>         unhandled(msg)
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> class OrderActor extends Actor {
>>>>>>   override def receive: Receive = {
>>>>>>     case msg: OrderJsonMsg =>
>>>>>>       val jsonMap = scala.collection.mutable.Map()
>>>>>>       // init JSON with order data.
>>>>>>       val order = Order.findInCacheById(msg.orderId)
>>>>>>       // NOTE HERE WE SEND MESSAGE BACK TO CUSTOMER ACTOR
>>>>>>       val selection = Akka.system().actorSelection("/user/orderActors")
>>>>>>       val futures =  order.customers.foreach(customerId => {
>>>>>>         val future = selection ? new CustomerNameMsg(customerId)
>>>>>>         future.onComplete(r => {
>>>>>>           // add data to JSON.
>>>>>>           sender ! jsonMap
>>>>>>         })
>>>>>>       })
>>>>>>     case msg =>
>>>>>>       unhandled(msg)
>>>>>>   }
>>>>>> }
>>>>>>
>>>>>>
>>>>>> On Wednesday, August 26, 2015 at 12:22:02 PM UTC-5, rrodseth wrote:
>>>>>>>
>>>>>>> Robert, in my case the REST endoint is using Spray. The per-request 
>>>>>>> actor has a reference to the RequestContext, and calls complete() on 
>>>>>>> it, 
>>>>>>> before stopping itself.
>>>>>>>
>>>>>>> I don't have time to check, but it might be modelled on this 
>>>>>>> Activator Template (which I think is referenced in the net-a-porter 
>>>>>>> blog 
>>>>>>> post).
>>>>>>>
>>>>>>> http://www.typesafe.com/activator/template/spray-actor-per-request
>>>>>>>
>>>>>>> On Wed, Aug 26, 2015 at 9:37 AM, Viktor Klang <[email protected]> 
>>>>>>> wrote:
>>>>>>>
>>>>>>>> I still have no idea what you mean by "wait" here. Do you mean 
>>>>>>>> "block"?
>>>>>>>> Please either show some code to illustrate or be more specific, 
>>>>>>>> it's impossible to answer otherwise and it just ends up being a lot of 
>>>>>>>> replying for nothing. :(
>>>>>>>>
>>>>>>>> -- 
>>>>>>>> Cheers,
>>>>>>>> √
>>>>>>>> On 26 Aug 2015 08:28, "kraythe" <[email protected]> wrote:
>>>>>>>>
>>>>>>>>> If you need the results of the generated futures then it waits for 
>>>>>>>>> them all to be completed. Process A needs the results of Process B in 
>>>>>>>>> order 
>>>>>>>>> to complete. This is a pretty common paradigm in our software. 
>>>>>>>>>
>>>>>>>>> -- Robert
>>>>>>>>>
>>>>>>>>> On Tuesday, August 25, 2015 at 9:43:11 PM UTC-5, √ wrote:
>>>>>>>>>>
>>>>>>>>>> how does that wait?
>>>>>>>>>>
>>>>>>>>>> -- 
>>>>>>>>>> Cheers,
>>>>>>>>>> √
>>>>>>>>>> On 25 Aug 2015 18:17, "kraythe" <[email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Call another actor using an ask pattern.
>>>>>>>>>>>
>>>>>>>>>>> On Tuesday, August 25, 2015 at 7:22:00 PM UTC-5, √ wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> define "wait for the responses to send back to the caller"
>>>>>>>>>>>>
>>>>>>>>>>>> On Tue, Aug 25, 2015 at 12:04 PM, kraythe <[email protected]> 
>>>>>>>>>>>> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Lets say that we create a pool of 5 actors using round robin 
>>>>>>>>>>>>> logic and then we send 5 messages at the same time and those 
>>>>>>>>>>>>> messages in 
>>>>>>>>>>>>> the course of being processed send another 5 messages each to the 
>>>>>>>>>>>>> actor and 
>>>>>>>>>>>>> wait for the responses to send back to the caller. If this was a 
>>>>>>>>>>>>> java 
>>>>>>>>>>>>> executor it would eventually deadlock waiting for the second set 
>>>>>>>>>>>>> of calls 
>>>>>>>>>>>>> to complete. Is the same deadlock possible with Akka? If not then 
>>>>>>>>>>>>> what 
>>>>>>>>>>>>> would prevent it? 
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks in advance. 
>>>>>>>>>>>>>
>>>>>>>>>>>>> -- 
>>>>>>>>>>>>> >>>>>>>>>> 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 http://groups.google.com/group/akka-user.
>>>>>>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> -- 
>>>>>>>>>>>> Cheers,
>>>>>>>>>>>> √
>>>>>>>>>>>>
>>>>>>>>>>> -- 
>>>>>>>>>>> >>>>>>>>>> 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 http://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 http://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 http://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 http://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 a topic in the 
>>>> Google Groups "Akka User List" group.
>>>> To unsubscribe from this topic, visit 
>>>> https://groups.google.com/d/topic/akka-user/WmK8EXGWKK0/unsubscribe.
>>>> To unsubscribe from this group and all its topics, send an email to 
>>>> [email protected].
>>>> To post to this group, send email to [email protected].
>>>> Visit this group at http://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 a topic in the 
>> Google Groups "Akka User List" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/akka-user/WmK8EXGWKK0/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> [email protected] <javascript:>.
>> To post to this group, send email to [email protected] 
>> <javascript:>.
>> Visit this group at http://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 http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to