Вызов блокирующего актера изнутри актера - PullRequest
1 голос
/ 10 августа 2009

Учитывая, что я вызываю Actor изнутри, реагирует ли этот блок на вызов Actor или он все еще обрабатывает другие запросы?

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

Ответы [ 2 ]

3 голосов
/ 10 августа 2009

!? всегда блокирует вызывающий поток. если он вызывается в середине блока реагирования субъекта, вызывающий субъект также блокируется.

Основная идея актеров - одиночный поток исполнения . Актер не перейдет к следующему сообщению, пока текущее не закончит обработку. Таким образом, разработчикам не нужно беспокоиться о параллелизме, если сообщения неизменяемы.

2 голосов
/ 10 августа 2009

См. этот вопрос о том, что субъекты не могут обрабатывать сообщения одновременно (т. Е. Каждый субъект обрабатывает свою входящую почту последовательно).

Я, конечно, не думаю, что это очень ясно из объяснений в Программирование в Scala . Вы можете (своего рода) достичь желаемого, создав актера на лету:

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 
   }
}

Конечно, актер на лету будет блокироваться, но он оставляет вашему исходному актеру возможность обрабатывать новые сообщения. Подсистема акторов будет создавать новые потоки вплоть до actors.maxPoolSize (по умолчанию 256), если все текущие рабочие потоки в пуле заняты.

...