views:

76

answers:

1

I'm a little confused about the flow in a system using domain events to build the read model. Particularly, how do we deal with the fact that the user expects data (and its view) to change when they complete a command, but due to our system architecture (non-blocking calls to publish events) the actual database might not change before the page is reloaded?

I'm hoping to move the design of one of our systems more inline with CQRS using events and a service bus.

Let's say my flow goes as such:

  1. User clicks button in View to perform Task of removing Payment Method from their Account.

  2. Controller calls PaymentMethodRemovalService, passing it accountId & paymentMethodId.

  3. Controller uses AccountRepository to retrieve Account and calls account.RemovePaymentMethod(id)

  4. Account validates that operation can occur and publishes event PaymentMethodRemovedMessage(accountId, paymentMethodId)

  5. Because event publishing is asynchronous, we now have to return from service and return view from the controller - but our actual data isn't updated yet!

  6. A handler, IHandle< PaymentMethodRemovedMessage >, hears the event and removes the actual row from the DB

So, what's a guy to do?

I could simply, say, remove the div that was displaying the payment method. This may work in an AJAX scenario, but what if I'm using Post-Redirect-Get to support non-JavaScript clients. Then I will be firing my Get and reading the data from the Query side of things, potentially before it's updated.

Do I just show a notification saying their request to remove the payment method has been submitted? (which doesn't seem to friendly, makes sense for submitting an order, but not for, say, changing an address).

Is there a way to reconcile implementing changes as decoupled asynchronous events and showing the user data that reflects their current change?

EDIT: My question is quite similar to http://stackoverflow.com/questions/3380431/cqrs-ddd-synching-reporting-database I have to say, the answer given there and also alluded to here, has a bit of a smell to it - wrangling the UI to show an update that's out of band with the read DB, so to speak. I was hoping for something a little cleaner.

+1  A: 

If you are locked into the Request/Response model you could adopt a Correlated Request/Response pattern. For specifics, check out the Async Pages sample in the NSB download. This demonstrates Request/Response in an ASP.NET setting. There are some ASP.NET MVC examples out there if that is more your thing.

When you introduce asynchronous processing you are accepting that the data will be stale. One can argue that the moment you query the DB the data is already old(network latency, rendering time etc.). Since the data is already old, we must ask how old is good enough?

One more thing to consider is that your processing is a bit out of order. Step 3 should be validating the command prior to sending it to the server and then steps 3, 4 would come after 6. The database should only be updated if the command is valid and the event should only be published if the database is successfully updated.

Adam Fyles