【问题标题】:Rebus - send command and wait for handlersRebus - 发送命令并等待处理程序
【发布时间】:2016-10-26 12:32:07
【问题描述】:

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

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

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

我阅读了很多博客和资料,并且我认为这种同步与使用总线的想法背道而驰......但是这样的用户操作需要是同步的:如何向用户呈现“插入成功的!”然后仍然看到一个空列表??

我希望得到答案,因为这个用例对我来说似乎很基础......

【问题讨论】:

    标签: synchronization cqrs rebus


    【解决方案1】:

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

    1. 禁用并刷新 - 这里的想法是在提交后禁用编辑字段,直到经过指定的时间段。我个人不喜欢这种方法,因为它会造成糟糕的用户体验,并且根据完成读取模型更新的时间可能仍然无法正常工作。

    2. 使用确认屏幕 - 这是处理结束屏幕的理想选择。比如“谢谢您的订单”或类似的。

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

    4. 轮询 - 正如已经建议的那样,您可以使用轮询或订阅读取模型。我也使用过这种方法,但将其与选项 3 结合使用。它适用于 React 等框架。

    您可以在此处阅读全文:4 Ways to Handle Eventual Consistency

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      【讨论】:

      • 感谢mookid的及时回复。我同意这是一个黑客,我不想这样做,因为在用户与之交互的应用程序中,这些地方不会很少......因此我想知道:开发了什么样的现实世界应用程序使用这种模式?服务器端服务?似乎 WebApps 不是理想的目标。还有:命令/事件与事件存储集成在一起,所以我可以使用另一种技术进行同步客户端操作,同时对同一个 mongo 和 SQL 存储进行操作吗?我现在有点迷茫……
      • 好吧——如果 IMO 认为他们的应用程序必须 100% 基于 CQRS 模式,他们会感到困惑。有时将不同类型的主数据保留为“普通实体”是有意义的,可能在编辑事件时记录它们,但仍以易于 CRUD 的方式存储。其他时候在整个过程中使用 CQRS 是有意义的,但我想说的是,在做出更改后需要立即显示更改的不可避免的要求可能表明这不是 CQRS 如此出色的领域。
      • 我会仔细考虑在哪里使用 CQRS/ES,在哪里不使用,谢谢提醒!
      猜你喜欢
      • 1970-01-01
      • 2015-12-05
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-27
      相关资源
      最近更新 更多