akka - ошибка шаблона ядра и планировщика - PullRequest
0 голосов
/ 04 октября 2019

Я реализовал шаблон ядра ошибки в образце, который я пытался создать.

Идея состояла в том, чтобы создать диалог между 3 участниками, но один не отвечает сразу, вам нужно отправить несколько сообщений, прежде чем получить ответ. Реализация должна быть устойчивой, даже если актеры выполняются в распределенной среде.

Итак, я создал дочерний актер, который повторяет попытку с использованием планировщика, и, когда ответ, наконец, приходит, дочернее уведомление является родительским и останавливается.

Даже если это решение работает хорошо, у меня мало сомнений.

Сначала в дочернем акторе я реализовал планировщик, который выполняет функцию каждые 50 миллисекунд, у меня мало сомнений относительно контекста выполнения. Я имею в виду, если код внутри метода sendMessage может изменить свой собственный субъект?

Когда актер планирует выполнение, что происходит, ждет, когда актер закончит свою работу?

import scala.concurrent.ExecutionContext.Implicits.global
import scala.language.postfixOps

var cancellableSchedule : Option[Cancellable] = None

var counter = 0
var maxCounter = 10

def receive = LoggingReceive {
    case r:MessageB2C_Ack => {
      log.info("ActorChildB - Received MessageB2C_Ack from " + sender())
      parentActor ! r
      context.stop(self)
    }
    case r:SendMessage => {
      log.info("ActorChildB - Received SendMessage from " + sender())
        sendScheduledMessage
    }
}

private def sendScheduledMessage(): Unit = {
    context.system.scheduler.scheduleOnce(0 milliseconds){
      sendMessage(0)
    }
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.language.postfixOps
    cancellableSchedule =  Option(context.system.scheduler.schedule(0 milliseconds, 50 millisecond){
      sendMessage()
    })
}

private def sendMessage(): Unit = {
      log.info("ActorChildB - sendMessage " + msg.getClass.getName + " to " + dest)
      if (counter < maxCounter) {
        dest ! msg
      log.info("ActorChildB - sendMessage " + msg.getClass.getName + " to " + dest)
      if (counter < maxCounter) {
        dest ! msg
        context.system.scheduler.scheduleOnce(50 milliseconds){
          sendMessage(counter + 1)
        }
        counter = counter + 1
      } else  {
        throw new MyRetryTimeoutException("Fine")
      }
}

override def postStop(): Unit = {
    cancellableSchedule.foreach(c => c.cancel())
    super.postStop()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...