来自 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中发现了类似的内容。
答案 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) }
因此,updateState
是Event => 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
处理程序代码块作为第二个参数来处理特定的持久性业务逻辑,该逻辑通常涉及更新参与者的内部状态。