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 akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
how does that wait?
--
Cheers,
√
26 aug 2015 kl. 17:40 skrev kraythe <kra...@gmail.com>:However, this has to be combined with some synchronous calls. Many parts of the system are Asynch but not all. We have users hitting web pages expecting to get certain data. We cant say "thanks for your submission and we will mail you your account information. "
We need to go fetch that information which might involve nested calls to several actors and that might recurse to some of the same actors. So we have a situation where user hits a web page and it invokes ask() on Actor A which has a collection of Data to be gotten from Actor B which in turn needs some info from Actor C. Finally Actor C requires a peice of information from actor A (a different piece of information) and then it is all returned. Now I cant complete process A until all of this is done and in an executor concurrent world that means DEADLOCK if each invocation doesn't have its own executor.
class A {
override def receive : Receive = {
case msg: Msg1 =>
// get domain object.
// For each id in a collection invoke ask() on actor B
// when all ask futures complete ... collect results and add to info
sender ! info
}
}
class B {
override def receive : Receive = {
case msg: Msg1 =>
// get domain object.
// Add some information to result.
// send ask() to actor A to get some piece of info.
sender ! info
}
}
I'd say using ask and blocking on it is still an improvement with pre 3.0 servlets.
With asynchronous servlets you can push the AsyncContext down in a message or use as in the ask future's onComplete callback.
With other frameworks (Netty, Jetty, Akka HTTP, non blocking 3.1 servlets, etc.) things will be even better.
There's just no need to use ask in other places, That's all. In other words it makes perfect sense to use it for the integration point between your existing blocking code and your new Akka based code and slowly change code to or add new asynchronous code.
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,
√
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)
}
}
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.
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 akka-user+...@googlegroups.com.