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 {
}
如所描述的那样
如何在接受任何其他命令之前初始化actor状态?
答案 0 :(得分:3)
您可以使用不同的行为:
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 重放事件时的行为。当重播完成时它会 使用新行为。