Как стать автором
Обновить
32
0
Alex Shkor @AlexShkor

Architect

Отправить сообщение
Без версий ничего не получится, так как важно знать в каком порядке воспроизводить события при восстановлении состояния агрегата. Event Stream — это поток событий для конкретного агрегата. Поток событий характеризуется тем что события с нем упорядочены. Например чтобы восстановить состояние агрегата User, нам нужен поток событий для этого юзера. У потока событий есть ID. Это тот же ID что и у Aggregate Root'a, в данном случае это ID пользователя. То есть получив поток событий с ID = 1 мы сможет по порядку воспроизвести все события которые происходили с пользователем с ID = 1. В итоге получится актуальное состояние пользователя. Если порядок поменять то мы уже не можем гарантировать что получим тоже самое состояние.
В Lokad IDDD Sample снэпшотов нету.
Ну давайте сначала определимся с терминологией. Агрегат — это не одна сущность, это несколько связанных сущностей, к которым мы можем обращаться только через Aggregare Root. Aggregare Root — это корневая сущность агрегата. Когда вы проектируете систему надо как-раз таки выделять агрегаты так, чтобы вам потом было удобно с ними работать в рамках вашей предметной области. Если у вас при изменение какой-то сущности важно знать состояние юзера, то поместите эту сущность в User агрегат. Выглядеть это будет как вложенный объект или коллекция объектов в объекте состояния агрегата. Для того чтобы изменить эту сущность вы будете обязаны обращаться через агрегат, а не на прямую. Нету ни какого смысла выделять по агрегату для каждой сущности из вашей предметной области, это лишь её усложнит. Как раз суть проектирования агрегатов и заключается в том чтобы грамотно скомпоновать сущности.
Спасибо. Даже не знал что они уже закончили, читал на гитхабе черновики.
Ну это чисто для удобства, чтобы не использовать рефлексию.
Можно обойтись и без динамиков и рефлексии, просто придется явно писать интерфейс для обработки каждого события.
Для всего этого есть read-model.
После того как события сохранились в Event Store они отсылаются на презентационный уровень в Read-model. Концептуально это что-то вроде Views в SQL. Вы обрабатываете там события еще раз и обнавляете read-базу. А в качестве read-базы может быть и SQL и Lucenе и MongoDB, или вообще все вместе.
Вы можете добавлять в события поля, просто при десериализации инициализировать их значениями по умолчанию. Переименовывать поля и удалять нельзя (это можно обойти если добавить аттрибуты порядка). Да write-база выглядит как key-value если не смотреть под копот. Но это write-база, больше вам от неё ничего не нужно. Вы даже не сможете прочитать состояние агрегата извне, у него есть только методы изменения состояния. Для отображение есть read-база, там уже может быть что угодно. Можете посмотреть пример к моей предыдущей статье.
События в снэпшоте не храняться. В нем как раз такие храниться проекциях всех предыдущий событий — состояние агрегата. При обработки новой команды вам нужное получить состояние агрегата, чтобы проверить ваши бизнес правила. Если снэпшотов нету — вы получаете состояние путем проигровывания всех событий данного агрегата (поток событий). Если у вас есть снэпшот, можно сказать что у вас есть промежуточное состояние. Вы восстанавливаете это состояние
_state = snapshot != null ? (UserState) snapshot.Payload : new UserState();

А потом уже сверху накатываете оставшиеся события.
При регенерации все снэпшоты удаляются, так как вы могли изменить класс состояния, и они уже не смогу десериализоваться.
Извините, не заметил вашего вопроса.
К сожалению проект про который я упомянул, коммерческий и у меня нет возможности выложить исходники. Но я постораюсь подробно его описать в одной из следующих статей. В частоности расскажу про его стрктуру и про то как мы его деплоим.
Если вам просто хочется посмотреть пример, то в моей статье есть ссылка на на тестовый проект который я написал специально для этой статьи.
Если у вас будут еще какие-то вопросы, можете обращаться ко мне по скайпу.
Подход себя действительно оправдывает. Слово «миграция» просто ушло из моего лексикона. На счет статистических данных, понимаю что всем очень интересно, но пока нету действительно большого количества ивентов на продакшене. Сейчас в районе 600к, и в последнее время я заметил увеличение роста. Основная проблема при большом количестве ивентов (т.е. операций записи) это конечно полная регенерация базы данных. В реал-тайме проблема с большим количеством операций записи решается очень просто — для этого есть snapshot'ы. На счет ускорения регенерации, это тема уже посложнее. Мы придумали уже много способов её ускорения. Пока самый действенный — это регенерация в памяти.
Могу рассказать про CQRS + Event Sourcing. Сейчас как раз пишу вторую часть статьи. Вот первая. Самые интересные и важные вопросы постараюсь осветить в грядущей статье.
Возможно там не все методы. Делал только нужные себе. Добавить новые там не составит проблем. Чуть что можете обращаться за помощью.
It.IsAny() точнее
Когда я писал свою реализацию типизированного UpdateBuilder'а для более ранней версии дляйвера, я сипользова Moq-style выражения. Выглядело это так.
IMongoUpdate update = Update.PushWrapped<Item2>(array1[Is.Any<int>()].array2, new Item2());

Если вам интересно могу скинуть исходники на гитхаб
Спасибо конечно, не не надо. Как по мне так лучше изучить 3-4 движка темплейтов, чем один XSLT.
И вообще зачем мне нужен XSLT, если есть наглядный, красивый, удобный Razor, который я отлично знаю, да и все мои коллеги знают. Поэтому я и хочу его же на клиент.
Вам в любом случае придется работать с другими движками, даже если вы будете переписывать все на XSLT всем с чем будете сталкиваться.
Давно ищу Razor engine для клиента. Реально было бы удобно использовать один шаблон и для клиента и для сервера. Тем более если использовать подход view model per view, то даже ничего переделывать не надо будет.
У меня в закладках есть несколько статей с msug с очень полезной для меня информацией.
Но вот не уверен что я на них попал с поиска.
Все будет, Рома, все будет =)
Да, действительно, если при подобной нагрузке на запись регенерация требует дополнительных оптимизаций. Я обязательно подниму эти вопросы в следующих статьях. Спасибо за отзыв.
Да, абсолютно верно. Это называется snapshot. Думаю следующая статья будет именно про них.

Информация

В рейтинге
Не участвует
Откуда
Минск, Минская обл., Беларусь
Дата рождения
Зарегистрирован
Активность