【问题标题】:Dealing with queued command handler response. CQRS处理排队的命令处理程序响应。 CQRS
【发布时间】:2015-03-13 07:41:08
【问题描述】:

考虑情况:

public class OrderController {
    IBus bus;

    public OrderController(IBus bus) {
        this.bus = bus;
    }

    public ActionResult Checkout(String orderId) {
        var command = new CheckoutOrderCommand(orderId);
        bus.Send(command);

        return Redirect("on-success-url");
    }
}

相应的命令处理程序(在单独的程序集中定义)正在等待处理传入的消息。

但是我们已经说过发送就可以了 return Redirect("on-success-url");

  1. 如果处理程序未能保存对域的更改怎么办?

    嗯,可以在命令处理程序端使用队列来发布响应,将 Web 应用程序订阅到队列中。

  2. 最终用户如何获得即时/同步的 ui 响应,这将反映对域所做的实际更改?我应该这样做吗?

  3. 通过消息总线处理传入命令是否仅适用于没有确认的后台任务?

【问题讨论】:

    标签: c# domain-driven-design messaging cqrs masstransit


    【解决方案1】:

    这来自«Busting some CQRS myths», Jimmy Bogard blog,您可能会感兴趣:

    误区 #4 – 命令即发即弃

    在您的工作中,有多少业务流程是真正的一劳永逸?您通常需要至少一个同步确认命令已被接收和接受。如果您正在执行命令的异步发送,您如何通知用户?电子邮件?他们同意吗?

    相反,对于需要繁重的命令来满足请求,我们确实有两件事要做:

    • 接受请求
    • 完成请求

    接受请求应该是同步的。实现不需要。但是对于异步实现的模型,我们可能仍然需要关联请求等的方法,这就是您经常看到工作流/流程/sagas 发挥作用的地方。

    我总是尝试让我的命令同步。如果处理时间很长,我会使用进程管理器或 saga 之类的东西。

    【讨论】:

      【解决方案2】:

      如果您确实想发送请求并等待响应,您可以使用IRequestClient 接口,并将MessageRequestClient 的实例添加到您的容器中 - 并使用该依赖项而不是直接使用IBus .这样您就可以等待请求的响应,并在 API 上返回一些内容。

      当然,您已经将控制器与服务的可用性相结合 - 这并不总是一件坏事 - 但需要注意一些事情。

      使用请求客户端的示例代码可以在文档中找到,这是一个与您描述的完全一样的网络案例。

      http://docs.masstransit-project.com/en/mt3/usage/request_response.html

      【讨论】:

        【解决方案3】:

        这在某种程度上取决于您的命令总线实现。一些系统允许命令处理程序将回复发送回原始发送者。

        在您的情况下,标准解决方案是不确认实际的 checkout,而是只确认命令的 receipt 并且现在正在处理结帐。对于结账,这通常完全没问题,因为无论如何处理订单都需要几个小时。

        如果您确实需要立即显示一些结果,则可以在给定时间范围内没有预期结果时轮询另一个服务的完成状态和/或超时。

        如果这对您来说太复杂,请不要使用异步命令总线,而是使用同步命令处理,将故障立即传播到客户端。

        【讨论】:

          猜你喜欢
          • 2021-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-03
          • 1970-01-01
          • 2021-07-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多