Rebus -发送命令并等待处理程序



我正在尝试使用CQRS/ES架构设置WebApp。我已经定义了一个模型实体,具有创建和编辑命令/事件。命令由相关的Saga处理。事件保存到mongo事件存储中,这是立即一致的存储。事件由写入最终一致SQL存储的反规格化器处理。

现在我面临着一个应该同步的来自WebApp的CRUD操作的问题:用户打开一个带有这些实体列表的页面,从最终一致的SQL存储中读取。最初它是空的。然后,用户编译一个表单来添加一个新实体。客户端对一个方法执行ajax调用,该方法向总线发出Create命令,然后返回void。

在成功回调时(确实如此,因为发出命令没有问题),客户端刷新实体列表。如果反规范化器仍然没有处理实体创建事件,并将其写入最终一致的SQL存储,则该页仍将显示一个空列表。我想要的是一种方法,使发出Create命令的方法等待反规格化器。

我读了很多博客和东西,我得到这样的同步与使用总线的想法相违背的想法…但是这样的用户操作需要是同步的:怎么可能用户看到"插入成功!",然后仍然看到一个空列表??

我希望得到一个答案,因为这个用例对我来说似乎是基本的…

不久前我写了一篇关于这个主题的博客文章。我提出了4种可能的解决方案。

  1. 禁用和刷新-这里的想法是禁用编辑字段一旦提交,直到指定的时间段已经过去。我个人不喜欢这种方法,因为它创造了糟糕的用户体验,并且仍然可能无法工作,这取决于完成读取模型更新的时间。

  2. 使用确认屏幕-这是一个理想的进程结束屏幕。比如"谢谢您的订单"或类似的。

  3. Fake It -这是一个很好的选择。它基于这样一个事实,即未能接收到异常或验证错误表示成功。因此,您可以假设读模型的新状态。我在生产中使用了这种方法,效果非常好。您需要小心使用版本号。它还提供了出色的用户体验。如果由于某种原因操作失败,您可以稍后通知用户。此方法还假定您已经完成了域内的验证和检查。它还有助于保持读取模型更新尽可能简单。

  4. Polling——正如已经建议的那样,您可以对读模型使用轮询或订阅。我也使用过这种方法,但将其与选项3结合使用。

你可以在这里阅读全文:处理最终一致性的4种方法

我认为这里的问题是,如果您需要命令是同步的,那么您可能选择了错误的技术来处理命令…

Rebus本质上是异步的,听起来你的整个设置也是围绕这个前提建立的。

我可以想出一些让异步看起来同步的方法,但首先我想指出的是,在我建议你在没有异步命令处理的情况下实现CQRS之前,你不应该在几个(非常少)的地方有这个要求(例如,通过使用Cirqus这样的东西,它可以等待一个或多个特定视图赶上,或者通过手工滚动它)。

话虽如此-:)我有一个关于如何使异步操作看起来同步的想法:只需通过轮询读存储直到您的更改可见!

您可以检测您的更改是否可见或多或少是通用的,范围从简单的轮询直到创建的用户弹出,到为您的命令提供各种相关ID,然后以某种方式将其传输到所有(重新)投影,然后可以由初始客户机发现。

但请认为这是一个hack。请看看是否可以避免假装同步的需要,或者考虑是否有其他技术更适合。

相关内容

  • 没有找到相关文章

最新更新