Search code examples
c#domain-driven-designmessagingcqrsmasstransit

Dealing with queued command handler response. CQRS


Consider the situation:

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");
    }
}

The corresponding command handler (defined in a separate assembly) is awaiting for the incomming message to be processed.

But we have already said that everything is ok by sending return Redirect("on-success-url");

  1. What if handler fails to save changes to the domain?

    Well, it is possible to use a queue on command handler side to publish response, to subscribe web application to the queue.

  2. How does the end user get immediate/synchronous ui response, which would reflect the real changes made to the domain? Should I do so?

  3. Is handling incomming commands by means of message bus is only good for a background tasks without acknowledgment?


Solution

  • This is taken from «Busting some CQRS myths», Jimmy Bogard blog that might be of interest to you:

    Myth #4 – Commands are fire-and-forget

    How many business processes in your line of work are truly fire and forget? You typically need at least a synchronous acknowledgement that the command was received and accepted. If you’re doing an async send of the command, how do you notify the user? Email? Are they OK with this?

    Instead, with commands that need heavy lifting to fulfill the request, we really have two things going on:

    • Accepting the request
    • Fulfilling the request

    Accepting the request should be synchronous. Fulfilling need not be. But for the model of an asynchronous fulfillment, we still will likely need ways of correlating requests etc., and this is where you often see workflows/processes/sagas come into play.

    I always try to make my commands synchronous. If there is a long process time, I'm using something like process manager or saga.