Акка рекомендую 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 при воспроизведении событий. Когда воспроизведение завершено, он будет использовать новое поведение.