Рекомендации по GUI для возможной согласованности?

При использовании распределенной и масштабируемой архитектуры часто требуется постоянная согласованность.

Графически, как справиться с этой возможной согласованностью?

Пользователи могут щелкнуть "Сохранить" и увидеть результат мгновенно... с возможной согласованностью это невозможно.

Как работать с графическим интерфейсом для таких сценариев?

Обратите внимание, что этот вопрос применяется как для настольных приложений, так и для веб-приложений.

PS: Я работаю с платформой Microsoft, но я думаю, что этот вопрос относится к любой технологии...

Ответ 1

A Пользовательский интерфейс на основе задач подходит для этой модели. Вы создаете и выполняете задачи из пользовательского интерфейса. Вы также можете иметь что-то вроде монитора состояния задачи, чтобы показать пользователю, когда задача выполнена.

Другой вариант - использовать какой-то пул с клиента. Вы отправляете команду и пул от клиента до тех пор, пока команда не будет завершена, и новые данные не будут доступны. В некоторых случаях у вас будет отсрочка, когда пользователь нажимает кнопку "Сохранить", когда увидит новую запись, но в большинстве случаев она должна быть почти синхронной.

Другим (хорошим?) вариантом является принятие/проектирование команд, которые не сбой. Это не тривиально, но вы можете иметь кэш на клиенте и добавлять данные из команды в этот кеш и отображать его пользователю даже до того, как команда будет выполнена. Если команда выходит из строя для какой-то неожиданной ситуации, тогда просто создайте хорошее сообщение "извините", чтобы ввести пользователя в заблуждение в течение нескольких секунд.

Вы также можете комбинировать методы выше.

Обычно конечная консистенция больше связана с проблемой бизнеса/домена, и вы должны иметь дело с ее специалистами по домену.

Ответ 2

Есть два способа:

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

Я предпочитаю первый вариант.

Ответ 3

Как уже упоминалось, пользовательский интерфейс на основе задач подходит для этого, и я бы использовал метод, который "покупает вам время" для распространения команды.

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

К тому моменту, когда они нажали на опцию, данные, надеюсь, были обновлены.

Кроме того, если вы используете пользовательский интерфейс на основе задач, вы можете проанализировать шаблоны выполнения задачи и использовать эти экраны "что бы вы хотели сделать дальше" для оптимизации пользовательского интерфейса. Подобно амазонке "другие люди также купили эти предметы".

Ответ 4

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

  • электронная почта;
  • SMS;
  • настраиваемый почтовый ящик (например, как входящий почтовый ящик);
  • что угодно.

Например, почтовый клиент/услуга:

  • Я отправляю почту по неправильному адресу;
  • почтовая служба говорит: "успешно отправлено письмо электронной почты";
  • Через несколько минут я получаю почту от службы: "Электронная почта не может быть доставлена".

Я считаю, что отличный способ информировать пользователя о недавнем сбое заключается в том, чтобы представить ему панель ошибок при навигации по приложению. Пользовательский жест может потребоваться для отклонения этого предупреждения и т.д.

Например:

enter image description here

Ответ 5

Я бы не стал обманывать пользователя или блокировать его от совершения каких-либо других действий. Я предпочел бы перейти к потоковой передаче данных в пользовательский интерфейс после того, как они будут признаны читающей стороной. Рассмотрим эти два случая:

  • Пользователи сохраняют данные и ожидают результата. Соединение установлено на сервер. После того, как они подтверждаются стороной с чтением, они передаются в UI, и пользовательский интерфейс обновляется.

  • Пользователь сохраняет данные и обновляет веб-страницу. После перезагрузки данные извлекаются из хранилища данных и устанавливается соединение для потоковой передачи. Если сторона чтения не обновляла хранилище данных в то же время, все же открытый поток и пользовательский интерфейс должны обновляться после того, как данные достигнут стороны чтения.

Почему потоковая передача со стороны чтения, а не непосредственно со стороны записи? Просто это было бы подтверждением того, что читающая сторона была достигнута. Из технического аспекта можно использовать Server-Sent Events.

Недостаток:

Результаты по-прежнему не будут сразу отражаться на стороне чтения. Но, по крайней мере, в большинстве случаев пользователь сможет продолжить свою работу, не блокируя пользовательский интерфейс.

Ответ 6

Я думаю, что другие ответы объединяют CQRS в целом и, в конечном счете, последовательность в частности. Пользовательский интерфейс на основе задач очень подходит для CQRS, но он не решает проблему со стабильной моделью чтения.

Во-первых, я хотел бы оспорить ваше утверждение:

Пользователи могут щелкнуть "Сохранить" и увидеть результат мгновенно... с возможной согласованностью это невозможно.

Чем вы занимаетесь? Почему невозможно сразу увидеть результат? Я думаю, что проблема здесь заключается в вашем определении результата.

Результат любого действия заключается в том, что это действие было выполнено. Существует множество способов показать это! Это зависит от того, какое действие вы хотите выполнить. Примеры:

  • Отправьте электронное письмо: если пользователь ввел правильный адрес электронной почты, почти гарантировано, что действие завершится успешно. Чтобы предотвратить неожиданные сбои, можно использовать длительные очереди, так как такие действия не нужно выполнять синхронно. Поэтому вы просто говорите "отправлено по электронной почте". Обычно вы видите такой ответ, когда вы запрашиваете reset свой пароль.

  • Обновите некоторую информацию в профиле пользователя: после того, как вы проверили новые данные на клиенте, скорее всего, команда будет успешной, так как единственное, что может произойти, это ошибка базы данных (если вы используете базу данных). Опять же, даже это можно смягчить, используя длительные очереди. В этом случае вы просто показываете обновленное поле в той же форме. Хорошей практикой для SPA является наличие полного хранилища данных на стороне клиента, например, Redux. В этом случае вы можете безопасно обновить сервер, отправив команду, а также обновив хранилище на стороне клиента, в результате чего пользовательский интерфейс отобразит последние данные. Отказ от ответственности: некоторые ответы относятся к этой технике как "обманывая пользователя", но я не согласен с этим определением.

  • Если у вас есть команды, которые подвержены ошибкам, вы можете использовать методы, которые уже описаны в других ответах, таких как Websockets или события на стороне сервера, чтобы сообщать об ошибках. Для этого требуется довольно много дополнительной работы. Вы также можете отправить команду и дождаться ответа или выполнить команды синхронно. Некоторые сказали бы, что "это не CQRS", но это будет просто еще одна догма, которую нужно оспаривать. Обеспечение выполнения команды в сочетании с предыдущей точкой (хранилищем данных на стороне клиента) будет хорошим решением.

Я не уверен, есть ли 100% -ный метод предотвращения пули, который позволяет вам всегда показывать нефиксированные данные из модели чтения. Я думаю, что это противоречит принципам CQRS. Даже с событиями в реальном времени вы будете получать только события, которые указывают на то, что вы пишете модель. Тем не менее, ваши прогнозы могли провалиться и реагировать на это совсем другая история.

Однако я бы не стал так много концентрироваться на этом вопросе. Дело в том, что хорошо протестированные прогнозы и почти гарантированные команды будут работать очень хорошо. Для обработки ошибок в 90% ситуаций достаточно иметь ручной или половинный ручной процесс для восстановления от этих ошибок. За последние 10% вы можете комбинировать общие сообщения об ошибке, выталкиваемые с сервера, говоря: "Извините, ваше действие XXX не удалось выполнить", и в действиях высшего приоритета может возникнуть некоторый творческий процесс, но на самом деле эти ситуации будут очень редко.