akka persist函数并非每次都处理

akka persist函数并非每次都处理,akka,persistence,Akka,Persistence,我使用akka的PersistentActor和集群中的切分来跟踪我的状态。我有一个“房间”,可以通过以下代码进行更新: case UpdateRoom(id, room, userId) => ((ret: ActorRef) => { (userRegion ? GetRoleForRoom(userId, id)).mapTo[String] map { role => if (role == "owner") { state = Some(roo

我使用akka的PersistentActor和集群中的切分来跟踪我的状态。我有一个“房间”,可以通过以下代码进行更新:

case UpdateRoom(id, room, userId) => ((ret: ActorRef) => {
  (userRegion ? GetRoleForRoom(userId, id)).mapTo[String] map { role =>
    if (role == "owner") {
      state = Some(room)
      ret ! Success(room)
      eventRegion ! RoomEventPackage(id, RoomUpdated(room))
      println("works")
      persist(RoomUpdated(room))(e => println("this doesn't always fire")
    } else {
      ret ! Failure(InsufficientRights(role, "Update Room"))
    }
  }
问题是,persist只在每隔一段时间工作一次,而函数的其余部分按预期工作。(“作品”每次打印一次,“这并不总是每隔一次,但两次)。 我总是要启动update命令两次来存储我的事件,但是在启动命令的两次中,它似乎都被存储了


我是否错过了akka persist的一个重要部分?

我认为您在Actor的世界中犯了一个严重的错误:从外部访问Actor(可变)状态。在您的情况下,这会在
ask
/
返回的
Future
回调中发生两次:

  • 更新状态时:
    state=Some(房间)
  • 调用
    persist
处理
Actor
中的询问并随后修改参与者状态的唯一安全方法是从ask的回调向同一参与者发送消息,为此,您可以使用
pipeTo

使用代码的简化版本来说明:

case UpdateRoom(id, room, userId) => 
  val answer = (userRegion ? GetRoleForRoom(userId, id)).mapTo[String] map(role => RoleForRoom(id, room, userId, role))
  answer piepTo self
case RoleForRoom(id, room, userId, room) => 
  if (role == "owner") {
    state = Some(room)
    eventRegion ! RoomEventPackage(id, RoomUpdated(room))
    persist(RoomUpdated(room))(e => println("this is safe"))
  }
另见: