本文介绍了只有在所有事件都被持久化后才更新actor状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the receive method of a persistent actor, I receive a bunch a events I want to persist, and only after all events are persisted, update again my state. How can I do that?

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() 调用不会阻塞,因此我不能在此之后放置代码.

Note that the persist() call is not blocking so I cannot put my code just after that.

更新:为什么我需要这个

这些新事件来自外部网络服务.我的持久参与者需要在其状态中存储最后一个事件 ID,当它接收到命令时,它将用于后续的 ws 调用.问题是这些命令可能同时出现,所以我需要某种锁定系统:

These new events come from an external web-service. My persistent actor needs to store in its state the last event id, which will be used for the subsequent ws call when it receives a command. The thing is that these commands may come concurrently, so I need some kind of locking system:

  • 接收到 ws 调用命令:存储下一个命令,直到这个命令完成(总而言之,一个布尔值)
  • 收到来自 ws 的响应:存储它们,更新状态并保存最后一个 id,对存储中的所有命令执行另一个单独的 ws 调用(我将命令发送者保持在能够在完成后全部响应)否则不要再隐藏命令.
  • Received ws call command: stash next commands until this one finishes (that is, to sum up, a boolean)
  • Received responses from ws: store them, update the state and save the last id, execute another, single ws call for all commands that are in the stash (I'm keeping the command senders to be able to respond to them all once done) otherwise don't stash commands anymore.

推荐答案

我还没有尝试过 defer,我最初的解决方案是给自己发送一个 PersistEventsDone 消息.它起作用是因为 persist 方法将存储所有传入的消息,直到所有事件处理程序都被执行.如果另一个命令出现在这个过程中,它是在 PersistEventsDone 之前还是之后并不重要:

I haven't tried defer yet, my initial solution was to send myself a PersistEventsDone message. It works because the persist method will stash all incoming messages until all the events handlers are executed. If another command came in the process, it doesn't really matter if it's before or after PersistEventsDone:

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

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

defer is a bit weird in my case because it requires an event I don't need. But it still looks more natural than my solution.

这篇关于只有在所有事件都被持久化后才更新actor状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 19:49