NServicebus / CQRS: как обрабатывать данные в интерфейсе пользователя?


Я читал текст Уди Дахана на [Command Query separation and SOA] [1]. Размышления о том, как я буду использовать это на практике в системе, над которой я сейчас работаю, вызвали некоторые вопросы...


1.

Рассмотрим следующую ситуацию, когда у меня есть клиентское приложение WPF, которое позволяет пользователю редактировать список записей:

Клиентское приложение запущено. При запуске он подписывается на службу команд, которая будет обрабатывать и публиковать изменения в записях и он запрашивает у службы WCF полный список записей. После получения списка записей все изменения (от других клиентов), которые могли быть опубликованы в очереди клиентов, пока она была занята ожиданием ответа от WCF, объединяются в список.

Теперь мне кажется, что существует (вероятно, очень маленький) шанс, что клиент подписывается сразу после обработки команды, ответственной за изменение, и что запрос службы WCS запускается непосредственно перед тем, как это же изменение было зафиксировано. база данных. В этой ситуации я получу неверные данные в моем клиенте, которые не синхронизируются (и никогда не будут синхронизированы) с базой данных (если клиентское приложение не будет перезапущено). Существует ли эта проблема на самом деле, и если да, то как ее следует решать?


2. Мой второй вопрос о том, как спроектировать / реализовать пользовательский интерфейс:

Теперь пользователь хочет изменить запись в списке; всплывает окно, данные изменяются и нажимается кнопка ok: мы отправляем сообщение. сообщение нашему обработчику команд для обработки этого изменения. Пользователь ожидает увидеть либо подтверждение (запись в списке изменяется), либо ошибку сообщение.

Теперь я могу попытаться обрабатывать вещи в пользовательском интерфейсе "синхронным" способом (пусть пользователь делает одну вещь за раз, и пусть он ждет успеха или неудачи, прежде чем ему разрешат делать что-либо еще) следующим образом:

  1. После того, как пользователь нажмет ok, отключите все элементы управления, чтобы дальнейшее редактирование не производилось. возможный.
  2. создайте сагу с таймаутом, который ждет ...? Ответное сообщение? Опубликованное уведомление от службы управления? И то, и другое?
  3. при получении ответного сообщения данные в списке изменяются, элементы управления включаются, и все готово -- или:
  4. наступает тайм-аут. Командное сообщение было помещено в очередь, поэтому изменение в конечном итоге будет выполнено, так что же делать? Покажите сообщение пользователю ("это занимает больше времени, чем ожидалось..."), включить все элементы управления и изменить данные в клиенте после получения уведомления от командной службы? Но что делать, если возвращается ошибка? Пользователь, возможно, начал делать что-то еще (возможно, редактируя другую запись), и появление сообщения об ошибке из предыдущей попытки редактирования не кажется хорошей идеей.

Другой подход, вероятно, состоял бы в том, чтобы просто отправить команду и позволить пользователю продолжать делать то, что ему нравится. Может быть, показать все выдающиеся команды в списке у пользователя интерфейс где-нибудь, с индикатором успеха или неудачи и возможностью для пользователя вывести сообщение об ошибке в случае неудачи. Учитывая, что тайм-ауты, как мы надеемся, являются исключительными и что ответы обычно должны быть получены в течение нескольких секунд, это означает, что в этом списке обычно должно быть не более 1 невыполненной команды.. Это и тот факт, что я не могу вспомнить, что я когда-либо видел пользовательский интерфейс, делающий вещи таким образом, означает, что это, вероятно, не очень хорошо. идея.

А ваш вопрос ? ;)

Ну, мне просто интересно, как другие люди решают эту проблему в своих пользовательских интерфейсах. Вероятно, есть лучшие способы обработки вещей в пользовательском интерфейсе, чем два, возможно, не очень умных способа, которые я придумал?

Приношу извинения за длинный текст и заранее благодарю за ответы.

[1]: http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/ "разделение командных запросов и SOA"

1 3

1 ответ:

Чтобы задать вопрос № 1, стандартным решением для запроса является создание хранилища постоянных запросов на стороне сервера, к которому клиент обращается с запросом RPC/ответами.

На вопрос № 2 Ответ очень сильно зависит от предметной области-видов команд, характера взаимодействия между пользователями. В качестве общего правила подумайте о том, как вы можете изменить пользовательский интерфейс и / или данные / обработку команд таким образом, что команды вряд ли когда-нибудь потерпят неудачу (если только речь не идет о вредоносных программах пользователи).

Надеюсь, это поможет.