这个 Process Manager 状态应该被持久化吗?

Should this Process Manager state be persisted?

我正在开发一个事件源电动汽车充电站管理系统,它连接到多个充电站。在这个领域,我想出了一个充电站的聚合,其中包括充电站的内部状态(是否连接,其连接器的内部状态)。

我可以向 Station 集合发出的命令是:

我想出了另一个代表充电会话的聚合,即用户与充电站连接器之间的交互。充电会话的创建与这些事件相结合,即如果连接器已被用户解锁,则创建一个会话,如果连接器的能量流已停止,则充电会话已完成。

我添加了一个监听事件的进程管理器:

对于第一个活动,创建会话非常简单。但是对于后者,它必须知道 Station(stationID)Connector(connectorID) 上正在进行的会话的 sessionID,因此它可以更新会话。

我不能简单地实现一个 GetSessionByConnectorID 函数,因为我正在实现一个事件源系统,我可以获得会话事件流的唯一方法是通过它的 ID,而不是通过它它的 ConnectorID(因为我只知道会话的 ConnectorID,当我将它加水时),所以我不知道如何实现 GetSessionByConnectorID 函数。

因此,进程管理器有一些内部内存状态 ((stationID, connectorID) -> (sessionID)),以跟踪 sessionID。但是,由于它在内存中,一旦进程管理器崩溃,我就失去了 (stationID, connectorID) <-> (sessionID) 之间的关联,我无法再正确响应 ConnectorEnergyFlowStopped 事件。

我该如何处理?我应该坚持流程管理器状态吗?我是否应该将它与 Process Manager 事件一起保存(这会很尴尬,因为它与无处不在的语言没有很好的关联,我在想 SessionProcessManagerReceivedStationConnectorUnlockedEvent-awkward-level)

编辑 - 新想法

我想到了其他事情,那就是删除内部进程管理器状态,并将 (stationID, connectorID) <-> (sessionID) 的关联放在 Station 聚合内。不幸的是,这意味着更高的耦合度(Station 必须知道何时创建会话,以及如何生成其 ID),但我认为它可能更简单(因为 Station 的事件是持久的)。因此 Station 会发出与会话相关的事件,其中包含 sessionID:

然而,将两者混在一起似乎有点奇怪,即使它只是会话的 ID。

我可以看到很多解决这个问题的方法,但我不熟悉你的领域,所以在这里抛出一些想法:

  • 使用进程管理器。流程管理器处理 long-运行ning 流程,需要根据定义持久化状态。消息驱动的流程管理器通常甚至不需要 运行 消息之间,因此它们处理事件、发出命令并关闭直到下一条消息。或者敲定。据我了解,这是最初的问题。

  • 从站点为每个会话发出会话 UUID。然后,站点将知道会话 ID,并且不需要进程管理器。

  • 使用查询模型。使用您需要的所有信息投影会话开始事件。当能量流停止时查询它以找出给定站和连接器的正在进行的会话,您甚至可能不需要用户 ID。项目 sessionClosed 事件并删除读取模型。

如果可能的话,我会选择第二个。最后一个在我的列表中排在第二位,由于相关的复杂性,流程管理器将是最后的选择。

对我来说,流程经理只是妨碍了这里。聚集体不应该无处不在,我认为你过分担心 Station 知道 Session

为什么不像 session = station.unlockConnector(sessionId) 这样富有表现力的东西呢?在 AR 上使用工厂方法来创建新的相关 AR 是很常见的,除非 Session 是一个完全独立的 BC。

此外,Session 的生命周期似乎与 Station 密切相关。当连接器关闭时,你能承受最终一致性吗?如果会话在连接器关闭的同时发生变化怎么办?

我觉得这个问题应该从自动售货机的角度来看待,希望下面的回答可以帮助你设计聚合。 https://sourcemaking.com/design_patterns/state