Акка рекомендую pratice для инициации `PersistentActor`

case class State(id: Long, remain: Int) {
  def take(t: Take) = copy(remain = remain - t.amount) 
}

object StateService {
  def getInitState(id: Long): Future[State]
}

sealed trait Evt
case class Init(id: Long) extends Evt
case class Take(id: Long, amount: Int) extends Evt

class FooActor extends PersistentActor  {
  var state: State

  def receiveCommand = {
    case Init(id) => ??? // how to
    case t: Take => persistAsync(t) {case e => state = state.take(t)}
  }
}

object FooActor {

}

Как описано в примере

Как я мог инициировать состояние актера, прежде чем принимать какие-либо другие команды?

1 ответ

Решение

Вы можете использовать различные варианты поведения:

case class State(id: Long, remain: Int)

object StateService {
  def getInitState(id: Long): Future[State]
}

sealed trait Evt
case class Init(id: Long) extends Evt

class FooActor extends PersistentActor  {
  var state: State

  import akka.pattern.pipe

  def notInitialized: Receive = {
    case Init(id) => 
      // for simplicity, failure is not handled
      StateService.getInitState(id) pipeTo self
    case st: State =>
      state = st
      context become initialized
  }

  def initialized: Receive = {
    case _ => // meh
  }

  def receiveCommand = notInitialized
}

object FooActor {

}

Вы даже можете полностью удалить изменяемое состояние, передав его в качестве параметров initialized поведение (например, initialized(state)). А что касается восстановления, из официальных документов Akka:

Также возможно переключаться между различными обработчиками команд во время обычной обработки и восстановления с помощью context.become() и context.unbecome(). Чтобы вернуть субъекта в то же состояние после восстановления, вам нужно проявить особую осторожность, чтобы выполнить те же переходы состояний с становлением и отказом в методе receiveRecover, как это делалось бы в обработчике команд. Обратите внимание, что при использовании стать из receiveRecover он по-прежнему будет использовать только поведение receiveRecover при воспроизведении событий. Когда воспроизведение завершено, он будет использовать новое поведение.

Другие вопросы по тегам