这个 Process Manager 状态应该被持久化吗?
Should this Process Manager state be persisted?
我正在开发一个事件源电动汽车充电站管理系统,它连接到多个充电站。在这个领域,我想出了一个充电站的聚合,其中包括充电站的内部状态(是否连接,其连接器的内部状态)。
我可以向 Station 集合发出的命令是:
UnlockConnector
,发出 StationConnectorUnlocked
StopConnectorEnergyFlow
,发出 StationConnectorEnergyFlowStopped
我想出了另一个代表充电会话的聚合,即用户与充电站连接器之间的交互。充电会话的创建与这些事件相结合,即如果连接器已被用户解锁,则创建一个会话,如果连接器的能量流已停止,则充电会话已完成。
我添加了一个监听事件的进程管理器:
StationConnectorUnlocked(stationID, connectorID)
-> SessionCreated(new uuid())
StationConnectorEnergyFlowStopped(stationID, connectorID)
-> SessionFinished(id???)
对于第一个活动,创建会话非常简单。但是对于后者,它必须知道 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:
StationConnectorUnlocked(stationID, connectorID, sessionID)
-> SessionCreated(sessionID)
StationConnectorEnergyFlowStopped(stationID, connectorID, sessionID)
-> SessionFinished(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
我正在开发一个事件源电动汽车充电站管理系统,它连接到多个充电站。在这个领域,我想出了一个充电站的聚合,其中包括充电站的内部状态(是否连接,其连接器的内部状态)。
我可以向 Station 集合发出的命令是:
UnlockConnector
,发出StationConnectorUnlocked
StopConnectorEnergyFlow
,发出StationConnectorEnergyFlowStopped
我想出了另一个代表充电会话的聚合,即用户与充电站连接器之间的交互。充电会话的创建与这些事件相结合,即如果连接器已被用户解锁,则创建一个会话,如果连接器的能量流已停止,则充电会话已完成。
我添加了一个监听事件的进程管理器:
StationConnectorUnlocked(stationID, connectorID)
->SessionCreated(new uuid())
StationConnectorEnergyFlowStopped(stationID, connectorID)
->SessionFinished(id???)
对于第一个活动,创建会话非常简单。但是对于后者,它必须知道 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:
StationConnectorUnlocked(stationID, connectorID, sessionID)
->SessionCreated(sessionID)
StationConnectorEnergyFlowStopped(stationID, connectorID, sessionID)
->SessionFinished(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