updateState方法中状态的使用(Persistent Actor)

时间:2018-12-11 13:28:08

标签: scala akka

来自 Akka食谱,来自持久演员一章的示例。在SamplePersistentActor.scala中有一些我不太了解的代码行。这是2个文件的完整代码。

SamplePersistentActor.scala:

  class SamplePersistenceActor extends PersistentActor {
  override val persistenceId = "unique-id-1"
  var state = ActiveUsers()
   def updateState(event:Event) = state = state.update(event)

  val receiveRecover: Receive = {
    case evt: Event => updateState(evt)
    case SnapshotOffer(_, snapshot: ActiveUsers) => state = snapshot
  }

 override val receiveCommand: Receive = {
    case UserUpdate(userId, Add) =>
      persist(AddUserEvent(userId))(updateState)
    case UserUpdate(userId, Remove) =>
      persist(RemoveUserEvent(userId))(updateState)
    case "snap" => saveSnapshot(state)
    case "print" => println(state)
  }

}

SamplePersistentModel.scala:

sealed trait UserAction
case object Add extends UserAction
case object Remove extends UserAction
case class UserUpdate(userId: String, action: UserAction)

sealed trait Event
case class AddUserEvent(userId: String) extends Event
case class RemoveUserEvent(userId: String) extends Event

case class ActiveUsers(users: Set[String] = Set.empty[String])
{
  def update(evt: Event)= evt match {
    case AddUserEvent(userId) => copy(users + userId)
    case RemoveUserEvent(userId) => copy(users.filterNot(_ == userId))
  }
  override def toString = s"$users"
}

我的问题 = state行中的= this.state(或我正确的是def updateState(event:Event) = state = state.update(event))的目的是什么。为什么我们不能只使用def updateState(event:Event) = state.update(event)

documentation example中发现了类似的内容。

2 个答案:

答案 0 :(得分:1)

  

为什么我们不能只使用def updateState(event:Event) = state.update(event)

重新分配给state变量的原因是update创建了一个新对象。换句话说,调用state.update不会使state突变;它将复制包含更新信息的state

您引用的示例就是这种情况:

var state = ExampleState()

def updateState(event: Evt): Unit =
  state = state.updated(event)

看一下ExampleState的代码,我们看到updated方法实际上创建了一个新的ExampleState对象:

def updated(evt: Evt): ExampleState = copy(evt.data :: events)

答案 1 :(得分:1)

在您的示例代码中:

def updateState(event: Event) = state = state.update(event)

等效于:

def updateState(event: Event) = { state = state.update(event) }

因此,updateStateEvent => Unit的函数,而这正是persist所期望的方法的第二个参数:

persist(AddUserEvent(userId))(updateState)

以下是Akka PersistentActor中方法persist的签名:

trait PersistentActor extends Eventsourced with PersistenceIdentity {
  // ...
  def persist[A](event: A)(handler: A => Unit): Unit = {
    internalPersist(event)(handler)
  }
  // ...
}

它期望EventType => Unit处理程序代码块作为第二个参数来处理特定的持久性业务逻辑,该逻辑通常涉及更新参与者的内部状态。

相关问题