1

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

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

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

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

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

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

我的想法:

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

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

3)我倾向于这个,但是读和写之间应该有一个明确的分离,这感觉像是违反了。这是允许的吗?

4

1 回答 1

2

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

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

对于一个很好的答案:您通常会从一个发送和发送电子邮件的设施开始,并将报告作为电子邮件发送成功与否的事件。这基本上是一个事件流——您的模型不会否决电子邮件是否已发送。

有了这部分,您实际上可以运行一个查询,询问“我现在需要发送哪些电子邮件?” ApplicationSaved您将事件与事件折叠起来EmailSent,从中计算出需要完成的新工作。

Rinat Abdullin 在撰写Evolving Business Processes a la Lokad时建议使用人工操作员来驱动流程。想象一下,构建一个屏幕,显示需要发送的电子邮件,然后在人们说要实际执行“它”的地方设置按钮,当人们点击按钮时,发送电子邮件的工作就会发生。

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

当您需要采取行动的所有信息都包含在您正在响应的事件的表示中时,通常会考虑将数据“推送”给订阅者。但是当订阅者需要有关先前状态的信息时,基于“拉”的方法通常更容易推理。交付的事件向项目发出信号以唤醒(减少延迟)。

Greg Young 在他的Polyglot Data演讲中详细介绍了 push vs pull 。

于 2018-04-09T20:14:28.620 回答