views:

239

answers:

2

Given I invoke an actor from inside react does this block the calling Actor or is it still processing other requests?

class worker extends Actor()
{
  def act() = {
    loop {
      react {
        msg =>
          var foo = another_actor !? 'bar' //Block here?
          println(foo)
      }
    }
}
+3  A: 

!? always blocks the calling thread. if it is invoke in middle of actor react block, the calling actor is blocked as well.

The main idea of actors is a single thread of execution. An actor will not proceed to the next message until the current one is finished processing. this way, the developers do not need to worry about concurrency as long as the messages are immuatable.

Walter Chang
+2  A: 

See this question about the fact that actors cannot process messages simulatneously (i.e. each actor processes its inbox sequentially).

I certainly don't think that this is very clear from the explanations in Programming in Scala. You can (sort of) achieve what you want by creating an on-the-fly actor:

loop {
   react {
      case Command(args) =>
         val f = other !! Request(args) //create a Future
         //now create inline actor
         val _this = self
         actor { //this creates an on-the-fly actor
           _this ! Result(args, f.get) //f.get is a blocking call              
         }
      case Result(args, result) =>
         //now process this 
   }
}

Of course, the on-the-fly actor will block, but it does leave your original actor able to process new messages. The actors subsystem will create new threads up to actors.maxPoolSize (default is 256) if all current pooled worker threads are busy.

oxbow_lakes