2016-10-26 3 views
2

Я пытаюсь настроить WebApp, используя архитектуры CQRS/ES. Я определил модельный объект с помощью команд Create/Edit/Events. Команды обрабатываются связанной сагой. События сохраняются в магазине событий mongo, который является сразу же совместимым магазином. События обрабатываются денормализаторами, которые записывают в последовательный SQL-хранилище.Rebus - отправить команду и ждать обработчиков

Теперь у меня возникла проблема с необходимостью синхронизации транзакций CRUD с WebApp: пользователь открывает страницу со списком этих сущностей, считая из последовательного хранилища SQL. Первоначально он пуст. Затем пользователь компилирует форму для добавления нового объекта. Клиент выполняет вызов ajax для метода, который выдает команду Create на шину, а затем возвращает void.

При успешном обратном вызове (и это потому, что при выдаче команды нет проблем) клиент обновляет список объектов. Если денормализатор все еще не обработал объект «Созданное событие» и записал его в последовательный SQL-хранилище, страница все равно будет содержать пустой список. Я хочу, чтобы метод, вызывающий команду Create, вызывает денормализатор.

Я читал много блогов и прочее, и я получаю представление о том, что такая синхронизация идет вразрез с идеей использования шины ... но такие пользовательские операции НЕОБХОДИМО быть синхронными: как пользователь может быть представлен " вставить успешно! " а затем все еще видите пустой список?

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

ответ

2

A назад назад a написал сообщение в блоге по этой теме. Я предложил 4 возможных решения.

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

  2. Используйте экран подтверждения - Это идеальное решение для завершения процесса. Как «спасибо за ваш заказ» или подобное.

  3. Fake It - Это хороший вариант. Это основано на том факте, что отказ в получении исключения или ошибки проверки указывает на успех. Поэтому вы можете принять новое состояние модели чтения. Я использовал этот подход в производстве и работал очень хорошо. Вам нужно быть осторожным с номерами версий. Он также предлагает отличный пользовательский интерфейс. Если по какой-то причине операция не удалась, вы всегда можете сообщить пользователю позже. Этот подход также предполагает, что вы тщательно проведете проверки и проверки внутри домена. Это также помогает сохранить обновленные версии моделей как можно более тривиальными.

  4. Опрос - Как уже было предложено, вы можете использовать опрос или подписку на прочитанную модель. Я также использовал этот подход, но объединил его с вариантом 3. Он хорошо работает с такими фреймворками, как React.

Вы можете прочитать полную запись здесь: 4 Ways to Handle Eventual Consistency

2

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

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

Я могу придумать пару способов сделать асинхронный просмотр синхронным, но сначала я хочу указать, что у вас НЕ должно быть этого требования более чем в нескольких (очень немногих) местах, прежде чем я порекомендую вас реализуйте свой CQRS без асинхронной обработки команд (например, используя что-то вроде Cirqus, которое может дождаться, когда один или несколько конкретных просмотров будут догоняющими, или вручную перевернув его).

Сказанное - :) У меня есть идея о том, как вы можете сделать синхронный асинхронный режим синхронным: просто опросив хранилище, пока ваше изменение не станет видимым!

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

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

+0

Спасибо mookid за быстрый ответ. Я согласен, что это взломать, и я не хочу этого делать, потому что мест не будет очень мало, в приложении, которое пользователь взаимодействует с ... Поэтому мне интересно: какие приложения реального мира разрабатываются с использованием этого шаблона? Службы на стороне сервера? Кажется, WebApps не идеальная цель. А также: команды/события интегрированы с хранилищем событий, поэтому могу ли я использовать другую технологию для синхронных операций с клиентом, действуя в тех же магазинах mongo и SQL? Я немного запутался прямо сейчас ... – Etchelon

+1

Ну, люди ИМО путают вещи, если считают, что они должны основывать 100% своего приложения на шаблоне CQRS. Иногда имеет смысл хранить разные типы masterdata как «обычные сущности», возможно, записывая события по мере их редактирования, но сохраняя их таким образом, чтобы их легко было CRUD. В других случаях имеет смысл использовать CQRS повсюду, но я бы сказал, что неизбежное требование необходимости показывать изменения сразу после того, как оно было сделано, может быть признаком того, что это не та область, где CQRS настолько хорош. – mookid8000

+0

Я подумаю, где использовать CQRS/ES, а где нет, спасибо за головы! – Etchelon

 Смежные вопросы

  • Нет связанных вопросов^_^