1
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 {

}

例として説明

他のコマンドを受け入れる前に、どうすればアクターの状態を初期化できますか?

4

1 に答える 1

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 メソッドで become および unbecome を使用して同じ状態遷移を実行するように特別な注意を払う必要があります。become from receiveRecover を使用する場合でも、イベントの再生時に receiveRecover 動作のみが使用されることに注意してください。リプレイが完了すると、新しい動作が使用されます。

于 2016-04-06T08:43:10.330 に答える