从事件处理程序内部加载事件?

时间:2018-04-09 16:49:24

标签: domain-driven-design cqrs event-sourcing ddd-repositories get-event-store

我们有一个使用GetEventStore的事件源系统,其中命令端和非常规化器在两个独立的进程中运行。

我有一个事件处理程序,它根据用户保存应用程序(ApplicationSaved事件)的结果发送电子邮件,我需要对其进行更改,以便只为给定的应用程序发送一次电子邮件。

我可以看到一些方法,但我不确定哪种方法是正确的。

1)我可以在读取存储中查看是否有匹配的应用程序但是当我的电子邮件处理程序正在处理事件时,不保证数据将存在。

2)我可以将一些东西附加到我的ApplicationSaved事件上,也许Revision会在每次后续保存时增加。然后,如果Revision为1,我只会发送电子邮件。

3)在我的事件处理程序中,我可以使用存储库从匹配客户的事件存储中加载事件,并构建一个与我的域中的聚合分开的聚合。它可以包含我可以用来做出决定的应用程序列表。

我的想法:

1)这似乎是禁止的,因为数据可能在读取存储中,也可能不在读取存储中

2)如果数据可以从事件流中导出,那么它不需要在事件本身上。

3)我倾向于这一点,但是这意味着读写两面之间的明显分离,这就像它违反了一样。这是允许的吗?

1 个答案:

答案 0 :(得分:2)

  

我可以看到一些方法,但我不确定哪种方法是正确的。

没有完美的答案 - 在大多数情况下,外部可观察到的副作用与您的记录簿无关;您可能总是有一些失败模式,其中发送电子邮件但系统不知道,或者系统记录电子邮件已发送但实际上发生了故障。

一个非常好的答案:您通常会开始使用发送电子邮件和报告的工具作为电子邮件成功发送的事件。这基本上是一个事件流 - 您的模型不会否决电子邮件是否已发送。

有了这个部分,你就可以有效地运行一个查询,询问"我现在需要发送哪些电子邮件?"您可以使用ApplicationSaved事件折叠EmailSent个事件,并根据需要完成的新工作进行计算。

撰写Evolving Business Processes a la Lokad的Rinat Abdullin建议使用人工操作员来推动这一过程。想象一下,构建一个屏幕,显示需要发送的电子邮件,然后按下人们说实际做的按钮,然后发送电子邮件的工作发生在人为点击按钮时。 / p>

人类正在看的是视图或投影,也就是说根据记录的事件计算的系统状态的读取模型。单击按钮会向"写入模型" (单击按钮事件告诉系统尝试发送电子邮件并写下结果)。

如果您需要采取行动的所有信息都包含在您要做出反应的事件的表示中,那么按照"推动"进行思考是正常的。数据给订户。但是,当订户需要有关先前状态的信息时,请" pull"基于方法通常更容易推理。交付的事件表示项目已唤醒(减少延迟)。

Greg Young在他的Polyglot Data演讲中详细介绍了推拉与拉动。