CQRS - как обрабатывать новые таблицы отчетов (или: как импортировать всю историю из хранилища событий)

Я изучил некоторые примеры реализации CQRS (Java/.Net), которые используют источник событий в качестве хранилища событий, а простой (No) SQL хранит как "хранилище отчетов".

Выглядит хорошо, но, кажется, что-то не хватает во всех реализациях примеров.

Как обрабатывать добавление новых хранилищ/экранов отчетов после того, как приложение поступило в производство? и как импортировать существующие (последние) данные из хранилища событий в новый хранилище отчетов?

Т.е:

Представьте себе базовое приложение CRM, основанное на DDD/CQRS. На каждом экране (на самом деле) есть собственный структурированный хранилище отчетов (таблица SQL). Все эти представления обновляются, используя обработчики, прослушивающие события домена (CustomerCreated/CustomerHasMoved и т.д.).

Одна из особенностей CRM заключается в том, что он может регистрировать телефонные звонки (событие PhoneCallLogged). Из-за ограничений по времени мы только выполнили регистрацию телефонных звонков в V1 CRM (просмотр и отчетность о том, кто обрабатывал, какой телефонный звонок будет реализован в V2)

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

Поэтому нам нужно добавить несколько экранов (представлений) и поддерживающих таблиц отчетов (в хранилище отчетов) и заполнить их данными, уже собранными в хранилище событий...

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

Все образцы EventRepository (DomainRepository) имеют только метод "GetById" и "Добавить", они не поддерживают получение всех совокупных корней за один раз, чтобы заполнить новую таблицу отчетов.

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

Любые предложения, рекомендации?

Спасибо заранее,

Ремко

Ответ 1

Вы повторно запускаете обработчик в существующем журнале событий (например, вы проигрываете старые события через новый обработчик событий)

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

Приветствия,

Грег

Ответ 2

Например, в Axon Framework это можно сделать с помощью:

JdbcEventStore eventStore = ...;

ReplayingCluster replayingCluster = new ReplayingCluster(
            new SimpleCluster("replaying"),
            eventStore,
            new NoTransactionManager(),
            0,
            new BackloggingIncomingMessageHandler());

replayingCluster.startReplay();

Повторение событий - это область, которая не полностью задокументирована и не имеет зрелой оснастки, но вот несколько отправных точек:

Ответ 3

"EventRepository" содержит только эти методы, потому что вам нужны только их в производстве.

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

Вы можете сделать это на своем сайте разработки следующим образом:

  • Загрузите журнал событий на сайт dev
  • Отправить все события обработчику денормализации
  • Переместите новый обработчик вида + на ваш производственный сайт
  • Запуск событий, которые произошли между ними
  • Теперь вы готовы