Этот актер Scala блокируется при создании нового актера в обработчике? - PullRequest
1 голос
/ 05 июня 2009

У меня есть следующий фрагмент кода:

actor {
  loop {
     react {
       case SomeEvent =>
         //I want to submit a piece of work to a queue and then send a response 
         //when that is finished. However, I don't want *this* actor to block
         val params = "Some args"
         val f: Future[Any] = myQueue.submitWork( params );
         actor {
           //await here
           val response = f.get
           publisher ! response
         }

     }
  }
}

Как я понял, внешний субъект не будет блокироваться на f.get, потому что это фактически выполняется отдельным актером (созданным внутри обработчика SomeEvent).

Это правильно?

1 Ответ

2 голосов
/ 05 июня 2009

Да, это правильно. Ваш внешний актер просто создаст актера и приостановит (дождитесь его следующего сообщения). Однако будьте очень осторожны с такими вещами. Внутренний субъект автоматически запускается в планировщике и обрабатывается потоком. Этот поток будет блокировать в этом Future (для меня это выглядит как java.util.concurrent.Future). Если вы делаете это достаточно много раз, вы можете столкнуться с проблемами голодания, когда все доступные потоки блокируются на Futures. Актер - это в основном рабочая очередь, поэтому вам следует использовать эту семантику.

Вот версия вашего кода с использованием библиотеки актеров Scalaz . Эта библиотека намного проще и понятнее, чем стандартные актеры Scala (источник буквально на полторы страницы). Это также приводит к гораздо более краткому коду:

actor {(e: SomeEvent) => promise { ... } to publisher }

Эта версия полностью не блокирует.

...