On Saturday, March 8, 2014 10:36:44 AM UTC-8, Andy C wrote:
>
> Hi,
>
> Most my stuff is reactive and async and Actors seems to be perfect to fit
> the bill with an exception of a certain legacy I/O. It has to be handled
> within Actor itself and it might take from seconds to even an hour to
> complete.
>
The usual approach is to have a dedicated dispatcher for the actors that
will do blocking IO. That way the actors that do not block will be fine.
Actors are multiplexed over a set of threads. So if an actor blocks it
holds onto a thread for the entire duration of the blocking call, making it
unavailable to other actors.
>
> So what is the best way to handle that within an Actor, can I just start
> that I/O and let it run within an actor? What is going to happen to
> messages coming to that actor? Can I create a Future/Promise inside which
> just will send an completion event to itself?
>
If you handle it within an actor, it will just block the actor tying up a
thread. If all your actors making blocking calls then this is a bad idea.
Other things you can do:
i) Use a dedicated dispatcher backed future pool like you suggested and
send completion events to the actors. This will not block your actors and
they'll be free to handle other messages. You can do the same thing with a
bunch of actors backed by a dispatcher. The programming style is just a bit
different. You can then configure your dispatcher appropriately to get good
performance.
ii) If your blocking library supports batching calls then I think actors
are the way to go. If you didn't use actors and used a thread(s) to do it
instead there is an intuitive and efficient way. Imagine a queue being used
to send requests for blocking IO to this thread. A good way to handle
requests on the receiving thread is:
1. Block, waiting for at least one message. Take as many messages as you
can from the incoming queue without blocking.
2. Perform a blocking but batched IO call with all your messages.
Dispatch all the responses to the requesting threads.
3. Go to 1.
This allows for very natural batching without the use of any timers and is
pretty efficient. Akka does seem to internally take many messages off the
inbox but AFAIK the actor is only fed these messages one by one through the
receive interface. There is no indication as to whether a message is part
of a batch or whether it is the last in a batch. If there was such a
facility then this would be a very simple solution. With timers one can
achieve the same with actors. Set a high throughput value on your blocking
actors (config) so multiple messages are taken off the inbox and fed
synchronously without going through the entire scheduling flow. Your
receive block can then just add the requests to an ArrayList or something.
You can then use a timer to actually trigger aggregating the blocking call
requests and perform one blocking call.
Something like this:
class BlockingActor extends Actor {
// Have a few of these actors backed by a dedicated threadpool.
def receive = {
case msg: BlockingRequest => {
// Received from other actors.
if (requestList isEmpty) {
startTimer()
// Timer length should probably be around the latency for a single
req/resp cycle,
// so batching doesn't cost much.
}
AddMsgToRequestList(msg)
}
case msg: TimerMsg => {
// Timer msg - batch all requests and make blocking call.
if (requestList nonEmpty) {
// Should be non empty. Why else did the timer fire?
batchRequest = batchRequestsAndEmptyRequestList(requestList)
results = makeBlockingCall(batchRequest)
dispatchResponses(results)
}
}
}
}
> In another words, what is idiomatic way of handling blocking I/O within
> Actors.
>
> Please advise,
> Andy
>
--
>>>>>>>>>> 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.