Лагом |Возвращаемые значения из процессора чтения стороны - PullRequest
0 голосов
/ 01 июня 2018

Мы используем Lagom для разработки нашего набора микросервисов.Хитрость здесь в том, что, хотя мы используем источник событий и сохраняем события в Cassandra, мы должны также хранить данные в одной из БД графа, поскольку именно она будет обслуживать большинство запросов из-за варианта использования..

Согласно документации Lagom, вся вставка в базу данных Graph (или любую другую базу данных) должна выполняться в ReadSideProcecssor после того, как обработчик команд сохранит события в cassandra, как следует из философии CQRS.

Теперь вот проблема, с которой мы сталкиваемся.Мы считаем, что ReadSideProcecssor является слушателем, который запускается после того, как события генерируются и сохраняются.Мы хотим вернуть ответ от ReadSideProcecssor к ServiceImpl.Пример, когда пользователь добавляется в систему, уникальный идентификатор, сгенерированный графом, должен быть возвращен как один из заголовков ответа.Как этого можно добиться в Lagom, поскольку ответ строится из setCommandHandler, а не из ReadSideProcessor.

Кроме того, мы должны убедиться, что в случае какой-либо ошибки на стороне графа API должно уведомлятьклиент, которому не удалось выполнить запрос, но опять-таки исключения, возникающие в ReadSideProcessor, не передаются ни в класс PersistentEntity, ни в ServiceImpl.Как это может быть достигнуто?

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 01 июня 2018

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

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

Чтобы объяснить, почему вам не нужна связь между ними - что произойдет, если событие сохраняется успешно, но обновлениена графе дб не получается?Возможно, граф дБ разбился.Команда должна повторить попытку?Нужно ли удалять событие?Что произойдет, если сам узел, выполняющий обновление, аварийно завершит работу, прежде чем у него появится возможность исправить проблему?Теперь ваша сторона чтения находится в несогласованном состоянии с вашими сущностями.Их соединение приводит к несогласованности во многих сценариях сбоев, например, когда вы обновляете свой адрес в коммунальной компании, но ваши счета по-прежнему идут на старый адрес, и вы связываетесь с ними, и они говорят «да, ваш новый адресобновляется в нашей системе ", но они все еще идут по старому адресу - это тот ужасный пользовательский опыт, на который вы подписываете своих пользователей, если вы пытаетесь соединить свою сторону чтения и сторону записи вместе.Отключение позволяет Lagom обеспечить согласованность между событиями, которые вы выдавали на стороне записи, и их потреблением на стороне чтения.

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

Теперь, если процессор на стороне чтения сталкивается с чем-то, чтоявляется недействительным, то у него есть два варианта.Один из вариантов - это может потерпеть неудачу.Во многих случаях это хороший вариант, так как если что-то недопустимо или несовместимо, то, скорее всего, у вас есть ошибка или какая-либо форма повреждения.То, что вы не хотите делать, это продолжать обработку, как будто все устраивает, так как это может сделать повреждение или несогласованность данных еще хуже.Вместо этого процессор на стороне чтения останавливается, ваш мониторинг должен затем обнаружить ошибку, и вы можете войти и разобраться, что это за ошибка или исправить ошибку.Конечно, в этом есть и недостатки, ваша сторона чтения начнет отставать от стороны записи, пока она не сможет обрабатывать новые события.Но это также является преимуществом CQRS - сторона записи может продолжать работать, продолжать обеспечивать согласованность и т. Д., Ошибка просто изолирована от стороны чтения и только при обновлении стороны чтения.Вместо того, чтобы вся ваша система не работала и отказывалась принимать новые запросы из-за этой ошибки, она изолирована от того, где проблема.

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

Теперь это накладывает определенные ограничения на то, что вы можете и не можете делать, но я не могу предвидеть тех, кто не знает, как именно вы их используете, чтобы знать, как их решать.Общим ограничением является проверка правильности набора - например, как вы гарантируете, что адреса электронной почты уникальны для одного пользователя в вашей системе?Грег Янг (парень из CQRS) написал этот пост в блоге об этих типах проблем:

http://codebetter.com/gregyoung/2010/08/12/eventual-consistency-and-set-validation/

...