Work with the response of the command processor in the queue. 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"); } } 

Appropriate command handler (defined in a separate assembly) expects when the message being processed will be processed.

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

  • What if the handler cannot save the changes to the domain?

    Well, you can use the queue on the side of the command handler to publish the response in order to subscribe to the web application in the queue.

  • How does the end user get an immediate / synchronous ui response that reflects the real changes made to the domain? Should I do this?

  • Is message bus processing useful only for background tasks without confirmation?

+5
source share
3 answers

This is taken from "Busting Some CQRS Myths," a Jimmy Bogard blog that might interest you:

Myth No. 4 - Commands are Fire and Forget

How many business processes in your line of work are really fire and forget? Usually you need at least synchronous confirmation that the command has been accepted and accepted. If you are sending asynchronously a command, how do you notify the user? Email address? Are they okay with that?

Instead, with teams requiring a heavy lift to complete the request, we really have two things:

  • Accepting Request
  • Query execution

Acceptance of the request must be synchronous. Execution is optional. But for the asynchronous execution model, we still need ways to correlate requests, etc., And it is here that you often see that processes / processes / sagas come into play.

I always try to make my teams synchronous. If there is a long process time, I use something like a process manager or saga.

+8
source

If you really want to send a request and wait for a response, you can use the IRequestClient interface and add a MessageRequestClient instance to your container - and use this dependency instead of using IBus directly. This will make it possible for you to wait for a response from the request and return something to the API .

Of course, you linked your controller to the availability of the service - and this is not always bad, but you need to know something.

An example of client request usage code can be found in the documentation, which is a web flag, just like you.

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

+3
source

It depends a little on the implementation of your command bus. Some systems allow command handlers to send responses back to the original sender.

The standard solution in your case is not to confirm the actual placing of the order, but simply to confirm receipt of the command, and the check is now processed. For inspections, this is usually completely normal, because orders take a couple of hours to process anyway.

If you really need to show some immediate results, you can poll another service for the completion state and / or timeout when there is no expected result for a certain period of time.

If this is too complicated for you, do not use the asynchronous command bus, but rather do synchronous command processing in which errors are immediately reported to the client.

+2
source

Source: https://habr.com/ru/post/1215282/


All Articles