Реализуйте тайм-аут в актерах - PullRequest
1 голос
/ 26 мая 2010

Я новичок в скале и актерах. Мне нужно реализовать такую ​​гипотетическую ситуацию: Сервер ожидает сообщений, если он не получает их, скажем, в течение 10 секунд, он отправляет сообщение клиенту. В противном случае он получает входящие сообщения. Если он внутри обрабатывает какое-то сообщение и приходит другое сообщение, его нужно поставить в очередь (я полагаю, это делается автоматически акторами scala).

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

Ответы [ 2 ]

6 голосов
/ 26 мая 2010

Как насчет этого?

loop {
  reactWithin(10000) {
    case TIMEOUT => // send message to client
    case work => // do work
  }
}
1 голос
/ 26 мая 2010

Даниэль дал лучший ответ на часть вопроса об условии отсутствия ввода. Итак, я отредактировал свое низшее решение.

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

Однако, если вы хотите установить фиксированную задержку с момента получения сообщения до момента его обработки, вы можете, например, создать актера, который будет работать немедленно, но обернет сообщение в запрос на задержку:

case class Delay(when: Long, what: Any) { }

// Inside class DelayingActor(workingActor: Actor)
case msg => workingActor ! Delay(delayValue + System.currentTimeMillis , msg)

Тогда рабочий актер

case Delay(t,msg) =>
  val t0 = System.currentTimeMillis
  if (t>t0) Thread.sleep( t - t0 )
  msg match {
    // Handle message
  }
...