Акка, как запустить мастер задачу и заблокировать на ней завершение? - PullRequest
3 голосов
/ 16 мая 2011

Я пытаюсь начать с akka в scala.В основной ветке scala я хотел бы запустить актера akka, отправить ему одно сообщение и заблокировать, пока этот актер не завершится.Каков наилучший способ сделать это?

Например, у меня есть тестовый актер, который просто многократно отправляет сообщения себе:

class Incrementer() extends Actor {

  val maxMessages = 5
  var counter = 0

  def receive() = {
    case DoIncr() => {
      if (counter < maxMessages) {
        counter += 1
        self ! DoIncr()
      } else {
        self.stop()
      }
    }
  }
}

, и он вызывается через:

val inc = actorOf(new Incrementer()).start()
val result = inc !! DoIncr()
println(result) // this should block this thread, but it doesn't seem to.

// do other stuff

Этот блок занимает чуть болееВыполнение 5000 мс вместо ожидаемых нескольких мсек, так что, похоже, это связано с будущим таймаутом по умолчанию - и программа фактически не завершается.Все, что я на самом деле пытаюсь сделать, - это рассчитать время отправки x количества сообщений.Что здесь происходит?

1 Ответ

4 голосов
/ 18 мая 2011

Как уже упоминал Виктор, для успешного завершения !! необходимо ответить на сообщение. 5-секундная задержка, по которой вы видите тайм-аут актера по умолчанию, который настраивается. Больше информации можно найти на сайте Akka .

Если вы используете forward для отправки сообщения вместо !, тогда self.reply ответит исходному отправителю.

Первое сообщение, которое вы отправляете актеру Akka, выполняет некоторые настройки, которых не происходит при обработке других сообщений. Обязательно примите это во внимание для вашего времени.

Исправленный код будет:

import akka.actor._

object DoIncr

class Incrementer extends Actor {
  val maxMessages = 5
  var counter = 0

  def receive = {
    case DoIncr =>
      if (counter < maxMessages) {
        counter += 1
        self forward DoIncr
      } else {
        self.reply(()) // replying with () since we have nothing better to say
        self.stop()
      }
  }
}

Помимо : я внес несколько других изменений, чтобы привести ваш код в соответствие с идиоматическим Scala. Ваш код работает без этих изменений, но теперь он выглядит как более типичный код Scala.

  • Классы дел без списков параметров устарели. Вместо этого используйте object s.
  • Если у вас есть класс без списка параметров, вы можете опустить круглые скобки
  • Actor s receive метод не имеет паренов; у вашего реализующего класса их тоже не должно быть.
  • Это просто вопрос стиля, но тело оператора case не требует скобок.
...