使用全局变量暂停事件源系统命令

时间:2018-07-17 16:29:15

标签: c# oop global-variables cqrs event-sourcing

在事件源系统中,我有一个终结点,在某些读取端不一致或损坏的情况下,管理员可以使用该端点来重建读取端数据库。

当命中该端点时,我想暂停(或排队)常规系统命令,以便无法对其进行处理。我想这样做,以便在重建数据存储时不会发出事件并且不会进行读取侧更新。如果发生这种情况,可以在重建过程中处理新的(实时)事件更新,并使读取的数据库DB处于不一致状态。


我本打算使用具有一些静态属性的静态类(本质上是模拟 global变量),但是读过这是不好的做法。

我的问题是:

  • 为什么在OO设计和C#中这种不好的做法?
  • 我可以使用哪些其他解决方案来代替全局变量来完成此类通信?

1 个答案:

答案 0 :(得分:3)

  

为什么在OO设计和C#中这种不好的做法? (使用全局变量)

社区中有很多talks,但是Very briefly, it makes program state unpredictable.

  

我可以使用哪些其他解决方案代替全局变量来完成此类通信?

如果仅需要重建Readmodel,则不应停止命令处理。 Write模型应该照常运行,因为它不需要读取端的数据(除非也有一些Sagas)。客户端需要处理命令,因此重建应透明进行。

相反,您应该使用另一个(临时)持久性(另一个数据库/表/集合/其他)创建Readmodel的另一个实例,然后使用它来重建状态。然后,重建完成后,您应该用这个新实例替换旧的/有故障的实例。

为使过渡尽可能平滑,即使在重新构建开始之前,新鲜的Readmodel也应订阅到事件流,但是它不应处理任何传入的事件。相反,应将它们与从事件存储或事件日志或您正在使用的任何事件源中提取的事件一起放入环形缓冲区

用于处理来自此环形缓冲区的事件的算法应为the oldest one is processed first。这样,在处理旧事件(重建开始之前生成的事件)之前,不会处理由新命令生成的新事件。

现在您有了一个干净的Readmodel来处理最新事件(追赶的Readmodel),您只需要用某种方式替换有问题的Readmodel,即在应用程序的组合根目录(依赖注入容器)中将其替换。 。有问题的Readmodel现在可以丢弃。