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

Pausing Event Sourced System Commands with Global Variable

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

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


我打算使用带有一些静态属性的静态 class(本质上是模拟一个 全局变量 ),但读到这是不好的做法。

我的问题是:

Why is this bad practice in OO design and C#? (using global variables)

社区上有很多关于此的 talks,但是 Very briefly, it makes program state unpredictable.

What other solutions can I use to accomplish this class communication in place of this global variable?

如果您只需要重建一个读取模型,则不应停止命令处理。 Write 模型应该像往常一样运行,因为它不需要读取端的数据(除非也有一些 Sagas)。客户端需要处理命令,因此重建应该透明地完成。

相反,您应该创建使用另一个(临时)持久性(另一个 database/table/collection/whatever)的 Readmodel 的另一个 实例 ,并使用它来重建状态。然后,重建完成后,您应该用这个新实例替换 old/faulty 实例。

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

从这个环形缓冲区处理事件的算法应该是the oldest one is processed first。这样,新命令生成的新事件直到旧事件(重建开始前生成的事件)被处理后才被处理。

现在你有一个干净的 Readmodel 正在处理最新的事件(一个追赶的 Readmodel)你只需要它以某种方式替换有故障的 Readmodel,即你在你的应用程序的组合根中替换它(依赖注入容器)。现在可以丢弃错误的 Readmodel。