私はPersistentActor
、特定のイベントに対して、彼の状態や行動を変化させることができる を持っています。状態を永続化するために問題はありませんが、状態の一部として動作を永続化する必要があることがわかりました。そうしないと、スナップショットからの障害回復の場合に正しく初期化されません。状態であり、動作ではありません。これを正しく達成する方法は?
現在、状態と動作のタプルを保存していますが、これが正しい方法かどうかはわかりません。私はあらゆる種類の提案やアイデアを受け入れます。FWIW、この種のアクターの使用例は、クラスター シャーディングのエントリです。ここでは、各エントリが (become/unbecome) を使用していくつかの状態を通過し、エントリの状態とその動作を保持する必要があります。どうもありがとう。
問題を示すコードは次のとおりです。
class FooActor extends PersistentActor with ActorLogging {
import FooActor._
var state: List[String] = Nil
def updateState(e: FooEvent): Unit = e match {
case Initialized ⇒ context become initialized
case Uninitialized ⇒ context become uninitialized
case Fooed(data) ⇒ state = data :: state
}
def uninitialized: Receive = {
case Init ⇒ persist(Initialized)(updateState)
}
def initialized: Receive = {
case Foo(data) ⇒ persist(Fooed(data))(updateState)
case Uninit ⇒ persist(Uninitialized)(updateState)
case Snap ⇒ saveSnapshot((state, receiveCommand)) // how to persist current behavior also?
}
def receiveRecover: Receive = {
case e: FooEvent ⇒ updateState(e)
// here, if I don't persist the behavior also, when the state is
// recovered, the actor would be in the uninitialized behavior and
// thus will not process any Foo commands
case SnapshotOffer(_, (_state: List[String], behavior: Receive)) ⇒
state = _state
context become behavior
}
def receiveCommand: Receive = uninitialized
val persistenceId = "foo-pid"
}
object FooActor {
case object Init
case object Uninit
case object Snap
case class Foo(data: String)
trait FooEvent
case object Initialized extends FooEvent
case object Uninitialized extends FooEvent
case class Fooed(data: String) extends FooEvent
}