Scala 仅在保留所有事件后更新参与者状态

Scala 仅在保留所有事件后更新参与者状态,scala,akka,akka-persistence,Scala,Akka,Akka Persistence,在persistent actor的receive方法中,我收到一堆我想要持久化的事件,只有在所有事件都持久化之后,才再次更新我的状态。我该怎么做 def receive: Receive = { ... case NewEvents(events) => persist(events) { singleEvent => // Update state using this single event } // After every eve

在persistent actor的receive方法中,我收到一堆我想要持久化的事件,只有在所有事件都持久化之后,才再次更新我的状态。我该怎么做

def receive: Receive = {
  ...
  case NewEvents(events) =>
    persist(events) { singleEvent =>
      // Update state using this single event
    }
    // After every events are persisted, do one more thing
}
请注意,persist()调用没有阻塞,因此我不能将代码放在阻塞之后


更新:我为什么需要这个

这些新事件来自外部web服务。我的persistent actor需要在其状态中存储最后一个事件id,当它接收到命令时,该id将用于后续的ws-call。问题是这些命令可能同时出现,所以我需要某种锁定系统:

  • 接收到的ws-call命令:隐藏下一个命令,直到该命令完成(即,总结起来,布尔值)
  • 接收到来自ws的响应:存储它们,更新状态并保存最后一个id,对存储中的所有命令执行另一个单独的ws调用(我让命令发送者能够在完成后对所有命令进行响应),否则不再存储命令

我还没有尝试过
延迟
,我最初的解决方案是给自己发送一条
persistEventsOne
消息。它之所以有效,是因为
persist
方法将隐藏所有传入消息,直到所有事件处理程序都执行为止。如果过程中出现了另一个命令,那么它是在
persistEventsOne
之前还是之后并不重要:

def receive: Receive = {
  ...
  case PersistEventsDone =>
    ...
  case NewEvents(events) =>
    persist(events) { singleEvent =>
      // Update state using this single event
    }
    self ! PersistEventsDone
}

defer
在我的例子中有点奇怪,因为它需要一个我不需要的事件。但它看起来仍然比我的解决方案更自然。

延迟是否符合您的目的?看起来很有希望,我会试试这个。谢谢我能问一下你的需求背后的原因吗?如果你解释你的目的,也许有更好的方法来实现它goal@DiegoMartinoia我更新了我的答案:)您还可以编写自己的持久性日志插件,作为现有插件的包装,然后在同步调用从此处终止后执行所需的任何操作