J'ai un PersistentActor
qui, pour un événement donné, peut muter son état et/ou son comportement. Pour persister l'état il n'y a pas de problème, mais il s'avère que j'ai besoin de persister le comportement aussi dans le cadre de l'état, sinon il ne sera pas initialisé correctement en cas de défaillance d'un snapshot, puisque l'instantané état et non le comportement. Comment y parvenir correctement?Comment persister comportement dans Akka Persistence?
Actuellement, ce que je fais est de sauvegarder un tuple de l'état et du comportement, mais je ne sais pas si c'est la bonne façon de le faire. Je suis ouvert à toutes sortes de suggestions et d'idées. FWIW, le cas d'utilisation de ce type d'acteur est comme une entrée pour le partitionnement de cluster, où j'ai besoin que chaque entrée passe par plusieurs états en utilisant (devenir/ne pas devenir) et persiste l'état des entrées ainsi que le comportement dans lequel elles se trouvaient. Merci beaucoup.
le code est ici illustrant le problème:
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
}
Vous pourriez envisager d'utiliser [Akka Persistent FSM] (http://doc.akka.io/docs/akka/snapshot/scala/persistence.html#Persistent_FSM) pour cela, bien qu'il soit encore expérimental. Il conserve les événements générés, ainsi que les transitions d'état, qui peuvent correspondre aux changements de comportements dont vous avez besoin pour votre application. – acjay