views:

408

answers:

1

I've been reading Udi Dahan's text on [Command Query separation and SOA][1]. Thinking about how I would use this in practice in a system I'm currently working on raised some questions...


1.

Consider the following situation where I have a WPF client application that allows the user to edit a list of entries:

The client application is started. At startup, it subscribes to the command service that will handle and publish changes to the entries and it queries a WCF service for the complete list of entries. After receiving the list of entries, any changes (by other clients) that may have been published to the clients queue while it was busy waiting for a reply from WCF are merged into the list.

Now to me there seems to be a (probably very small) chance that the client subscribes just after a command responsible for a change was handled and that the WCS service's query is started just before the same change has been committed to the database. In this situation I'll end up with incorrect data in my client that is not (and will never get into) sync with the database (unless the client application is restarted). Does this problem really exist and if it does, how should it be handled?


2. My second question is about how to design/implement the user interface:

The user now wants to change an entry in the list; a windows pops up, data is changed and the ok button is pressed: we send a message to our command handler to handle this change. The user expects to see either a confirmation (the entry in the list changes) or an error message.

Now I can try to handle things in the user interface in a 'synchronous' way (let the user do one thing at a time, and let him wait for success or failure before he's allowed to do anything else) the following way:

  1. After the user presses ok, disable all controls so no further editing is possible.
  2. Create a Saga with a timeout that waits for ...? The response message? The published notification from the command service? Both?
  3. When a response message is received the data in the list is changed, controls are enabled and we're done -- or:
  4. A timeout occurs. The command message has been queued, so the change will eventually be performed, so what to do? Show a message to the user ("this is taking longer than expected..."), enable all controls and change the data in the client once the notification is received from the command service? But what if an error is returned? The user may have started doing something else (maybe editing another entry) and popping up an error message from a previous edit attempt doesn't seem like a good idea.

Another approach would probably be to just send the command and let the user continue with whatever he likes to do next. Maybe show all outstanding commands in a list in the user interface somewhere, with an indicator of success or failure and the possibility for the user to display the error message in case of a failure. Given that timeouts are hopefully exceptional and that responses should normally be received within a few seconds would mean that this list should normally have at most 1 outstanding command in it.. That and the fact that I can't remember that I've ever seen a user interface doing things this way means that it's probably not a good idea.

And your question is ? ;)

Well, I'm just wondering about how other people are solving this in their user interfaces. Likely there are better ways of handling things in the UI than the two maybe not-so-clever ways that I came up with?

Apologies for the long text and thanks in advance for your replies.

[1]: http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/"Command Query separation and SOA"

+2  A: 

To question number 1, the standard solution for querying is to create a server-side persistent query store that the client RPC-request/responses against.

To question number 2, the answer is very much dependent on the domain - the kinds of commands, the nature of inter-user collaboration. As an overarching rule, think of ways you can change the UI and/or the data/handling of the commands such that commands will hardly ever fail (unless we're talking about malicious users).

Hope that helps.

Udi Dahan