Давайте предположим, что мы хотим внедрить небольшую подсистему безопасности для финансового приложения, которая предупреждает пользователей по электронной почте, если обнаруживается странная картина. В этом примере шаблон будет состоять из трех транзакций, как показано на рисунке. Подсистема безопасности может читать события из основной системы из очереди.
Я хотел бы получить предупреждение, которое является прямым следствием событий, происходящих в системе, без промежуточного представления, которое моделирует текущее состояние шаблона.
- Мониторинг активирован
- Транзакция обработана
- Транзакция обработана
- Транзакция обработана
- Оповещение сработало (id: 123)
- Email для оповещения отправлено (для id: 123)
- Транзакция обработана
Имея это в виду, я подумал, что источник событий может быть применим здесь очень хорошо, хотя у меня есть вопрос без четкого ответа. Оповещение, запущенное в этом примере, имеет явный побочный эффект: необходимо отправить электронное письмо, а это может произойти только один раз. Следовательно, этого не должно происходить при воспроизведении всех событий агрегата.
В какой-то степени я вижу электронное письмо, которое необходимо отправить, аналогично материализации, сгенерированной стороной запроса, которую я видел так много раз в литературе по поиску CQRS / Event, хотя с не столь тонким отличием.
В этой литературе сторона запроса построена из обработчиков событий, которые могут генерировать материализацию состояния в данной точке, снова считывая все события. В этом случае, однако, это не может быть достигнуто в точности так по причинам, объясненным ранее. Идея о том, что каждое состояние преходяще, здесь не так хороша . Нам нужно зафиксировать тот факт, что предупреждение было отправлено куда-то.
Простым решением для меня было бы иметь другую таблицу или структуру, в которой вы ведете записи предупреждений, которые были ранее активированы. Поскольку у нас есть идентификатор, мы сможем проверить, было ли ранее выдано предупреждение с таким же идентификатором. Наличие этой информации сделает идемпотент SendAlertCommand. Можно ввести несколько команд, но побочный эффект произойдет только один раз.
Даже имея в виду это решение, я не знаю, является ли это намеком на то, что с этой архитектурой что-то не так для этой проблемы.
- Правильный ли мой подход?
- Есть ли место, где я могу найти больше информации об этом?
Странно, что я не смог найти больше информации об этом. Возможно, я использовал неправильную формулировку.
Огромное спасибо!