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.

Reply via email to